I learned scheme first and now I am moving to lisp.
I am wondering why there is no call/cc in lisp. It seems to be potentially useful. For example, in the book 'On Lisp', a significant part of this excellent book seems to consists of reinventing various cut down versions of call/cc.
(Call/cc is a way to save the current state of the program in a variable. You can use the variable later on onto resume processing at that point. It can be used for coroutines, exception handling, nondeterministic search, etc.)
The lisp approach seems to be to provide specific features for the common uses of call/cc, such as exception handling. To my naive point of view this seems to be contrary to the usual lisp approach. Normally you would expect to have a very general facility, with macros/special forms used to provide specialised versions. An example of this approach would be the iteration facilities which can be constructed from goto and recursion, but are much more convenient.
Three possibilities as to why call/cc is not in lisp occur to me:
1. For some reason it is not seen as useful. But to me it seems useful.
2. It is too hard to implement efficiently - period. I don't know enough about implementing functional languages to say for sure, though it does look like it might be a challenge to implement e.g. maybe you need to copy the stack.
3. It can be implemented efficiently in scheme, but is too hard to implement efficiently in lisp. I can't see any reason why this would be the case. Lisp is bigger than scheme but the core of the language does not look that much bigger to me.
Can anyone shed any light on this? If someone wants to use this as a springboard for a lisp versus scheme discussion, please start another thread. (In my view lisp and scheme both have good reasons to exist.
Tim Josling wrote: > I learned scheme first and now I am moving to lisp.
> I am wondering why there is no call/cc in lisp. It seems to be potentially > useful. For example, in the book 'On Lisp', a significant part of this > excellent book seems to consists of reinventing various cut down versions of > call/cc.
The standard argument I have read several times is that call/cc turned out to be too powerful and is hard to use correctly. For example, I recall reading a paper that formally proved that continuations and exception handling are _not_ compatible. If you are interested I can try to find out again which paper this was.
I don't know the motivations for including a call/cc simulation in "On Lisp". To me it seemed a little like a defensive argument, but this is only my gut feeling. I don't have enough experience to be able to tell if continuations are really useful beyond language design experiments, but I would definitely also be interested to hear what other, more experienced people think.
Tim Josling <t...@melbpc.org.au> writes: > I learned scheme first and now I am moving to lisp.
> I am wondering why there is no call/cc in lisp. It seems to be > potentially useful. For example, in the book 'On Lisp', a > significant part of this excellent book seems to consists of > reinventing various cut down versions of call/cc.
> (Call/cc is a way to save the current state of the program in a > variable. You can use the variable later on onto resume processing > at that point. It can be used for coroutines, exception handling, > nondeterministic search, etc.)
> The lisp approach seems to be to provide specific features for the > common uses of call/cc, such as exception handling. To my naive > point of view this seems to be contrary to the usual lisp > approach. Normally you would expect to have a very general facility, > with macros/special forms used to provide specialised versions. An > example of this approach would be the iteration facilities which can > be constructed from goto and recursion, but are much more > convenient.
> Three possibilities as to why call/cc is not in lisp occur to me:
> 1. For some reason it is not seen as useful. But to me it seems > useful.
> 2. It is too hard to implement efficiently - period. I don't know > enough about implementing functional languages to say for sure, > though it does look like it might be a challenge to implement > e.g. maybe you need to copy the stack.
> 3. It can be implemented efficiently in scheme, but is too hard to > implement efficiently in lisp. I can't see any reason why this would > be the case. Lisp is bigger than scheme but the core of the language > does not look that much bigger to me.
Tim Josling wrote: > I am wondering why there is no call/cc in lisp. It seems to be potentially > useful. For example, in the book 'On Lisp', a significant part of this > excellent book seems to consists of reinventing various cut down versions of > call/cc.
A Google groups search for call/cc in c.l.l. gives about 496 hits. Reading some of those would probably answer most of your questions, you're not the first to ask this.
In article <3D98D523.CE0C2...@melbpc.org.au>, Tim Josling <t...@melbpc.org.au> wrote:
>I am wondering why there is no call/cc in lisp. It seems to be potentially >useful. For example, in the book 'On Lisp', a significant part of this >excellent book seems to consists of reinventing various cut down versions of >call/cc.
Baby steps, please. The voices of reason are still negotiating to get mandatory tail-call elimination into the next iteration of CL. call/cc can wait.
d...@goldshoe.gte.com (Dorai Sitaram) writes: > In article <3D98D523.CE0C2...@melbpc.org.au>, > Tim Josling <t...@melbpc.org.au> wrote: > >I am wondering why there is no call/cc in lisp. It seems to be potentially > >useful. For example, in the book 'On Lisp', a significant part of this > >excellent book seems to consists of reinventing various cut down versions of > >call/cc.
> Baby steps, please. The voices of reason are > still negotiating to get mandatory tail-call > elimination into the next iteration of CL. call/cc can > wait.
If the "voices of reason" could come up with a specification of what "mandatory tail-call elimination" actually means, phrased in a fashion that is actually understandable by implementors, ideally with a reference implementation of the specification's semantics (for cmucl or one of the other "free" implementations, for extra credit, so everything is clear), then perhaps those people working on CL implementations who seem to be behaving so "unreasonably" might actually sit up and take notice.
But until someone comes up with a proposal dealing with whether FOO is in a "mandatory tail-call" position in the following: (let ((*print-length* 3)) (foo)) [ bearing in mind that FOO could end up throwing an error, putting you into the debugger, where complex restarts may be available ] and sundry other issues, then I think describing people who don't actively work towards implementing more tail-call elimination by implication as "unreasonable" is a little bit rich.
Christophe -- http://www-jcsu.jesus.cam.ac.uk/~csr21/ +44 1223 510 299/+44 7729 383 757 (set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b))) (defvar b "~&Just another Lisp hacker~%") (pprint #36rJesusCollegeCambridge)
Tim Josling wrote: > I am wondering why there is no call/cc in lisp. It seems to be potentially > useful. For example, in the book 'On Lisp', a significant part of this > excellent book seems to consists of reinventing various cut down versions of > call/cc.
...
> Three possibilities as to why call/cc is not in lisp occur to me:
> 1. For some reason it is not seen as useful. But to me it seems useful.
> 2. It is too hard to implement efficiently - period. I don't know enough about > implementing functional languages to say for sure, though it does look like it > might be a challenge to implement e.g. maybe you need to copy the stack.
> 3. It can be implemented efficiently in scheme, but is too hard to implement > efficiently in lisp. I can't see any reason why this would be the case. Lisp > is bigger than scheme but the core of the language does not look that much > bigger to me.
1. Efficient implementability was a major consideration when Common Lisp was being defined. call/cc is very difficult to implement efficiently. I don't think it would add substantially more difficulty to CL than it does to Scheme, but it adds quite a lot to Scheme. There's one reason why it might hurt CL more than Scheme: producing efficient code in the presence of call/cc requires sophisticated control-flow analysis, which is harder for very large systems. CL is, on the whole, much more interested in very large systems than Scheme is.
2. call/cc is indeed useful, but most of the things it's useful for can be provided without needing the machinery of call/cc. The condition system, throw/catch, etc, provide most of what you'd use call/cc for. But, indeed, not everything.
3. Common Lisp was more a consolidation of existing practice than a locus of innovation. Among the Lisp users and implementors involved in Common Lisp, call/cc just wasn't an issue.
Perhaps I should expand on the statement that "call/cc is very difficult to implement efficiently". It's not just that making call/cc work fast is difficult; it's that having a system that contains call/cc makes *other* things harder to do effficiently. The trouble is that if you can't prove that *nothing* in a given piece of code can cause an instance of its continuation to escape, then a bunch of optimizations on that code are blocked. But any call to an external function can cause the current continuation to escape. So you end up having to do whole-program analysis, and that hurts.
-- Gareth McCaughan Gareth.McCaug...@pobox.com .sig under construc
I think Kent Pitman's article -- kindly reference by Edi Weitz -- provides an excellent answer to why call/cc might not such a good idea. However, I also think there are some other problems as well.
Tim Josling wrote:
> Three possibilities as to why call/cc is not in lisp occur to me: > 1. For some reason it is not seen as useful. But to me it seems useful. How do you currently use call/cc? As Paul Graham demonstrates, you can get much of functionality of call/cc. So when do you need to go beyond this? FWIW I don't think the marginal gains are worth losing the kind of guarantees stuff like unwind-protect give you.
> 2. It is too hard to implement efficiently - period. If you were writing a implementation that you wanted to run with more than one thread of excution at a time, how would you integrate this with the use of call/cc? (I really don't know the answer to this. I realise that threading is not in the ANSI standard. However, there are implementations out there with extensions the provide good threading support. I would then see call/cc as being are *really* big headache. So again, why bother?
> I don't know enough about implementing functional languages to say for > sure... Hmmm. I could read this as saying that common lisp *is* a functional language. Are you sure?
> In article <3D98D523.CE0C2...@melbpc.org.au>, > Tim Josling <t...@melbpc.org.au> wrote: > >I am wondering why there is no call/cc in lisp. It seems to be potentially > >useful. For example, in the book 'On Lisp', a significant part of this > >excellent book seems to consists of reinventing various cut down versions of > >call/cc.
> Baby steps, please. The voices of reason are > still negotiating to get mandatory tail-call > elimination into the next iteration of CL. call/cc can > wait.
Tail call elimination does not change the semantics of the language (at worst, it breaks them), while continue-with-current-call and it's ilk actually add something fundamentally new, and not directly possible in CL (though you could easily implement call/cc in Interlisp, as stacks were first class. Those were the days!). The best you can do in CL is use dynamic closures (not actually part of CL but a common extension, aka coroutines or stack groups), but it can be difficult to correctly close over the entire virtual machine state without significant (human and machine) effort. If all you need is downward closures, life is considerably simpler, and there are several packages supplying this functionality on the net.
* Dorai Sitaram wrote: > Baby steps, please. The voices of reason are > still negotiating to get mandatory tail-call > elimination into the next iteration of CL. call/cc can > wait.
You are just trying to be offensive here, aren't you? Why? What purpose does this serve? Could you perhaps not write something constuctive, instead?
* Tim Josling wrote: > The lisp approach seems to be to provide specific features for the > common uses of call/cc, such as exception handling. To my naive > point of view this seems to be contrary to the usual lisp > approach. Normally you would expect to have a very general facility, > with macros/special forms used to provide specialised versions. An > example of this approach would be the iteration facilities which can > be constructed from goto and recursion, but are much more > convenient.
There are a number of reasons for not having call/cc. One is that the moment you have it you have to deal with a million issues of code that might be run many times. For instance the moment you have call/cc things like UNWIND-PROTECT become no good - when (if ever) should the protecting forms happen. So instead you need something like DYNAMIC-WIND which gets to specify code that runs on the way out and then again on the way back in. So everything now looks kind of nice (if about 10x as complicated to reason about as before). But now what if you want to interact with external resources like, say, files, or streams. How should WITH-OPEN-STREAM work in the presence of upward continuations? When exactly is it safe to close the stream, since you won't get it back once you do, no matter how much cleverness you do with DYNAMIC-WIND.
This has all been discussed *many* times on cll before - do a google search. Inevitably these discussions degenerate into sniping between scheme people and Lisp people, just as this one will (I suppose Dorai Siteram's post could charitably be seen as an attempt to stifle the thread at birth by causing such degeneration to happen instantly).
And I think your take on `the Lisp approach' is basically completely backward, at least as regards CL. The CL approach is to be pragmatic - implement what can be agreed on and what can be seen to be efficiently implementable and useful: don't implement stuff that suddenly opens huge questions about what everything means, or whether it can be implemented efficiently.
In article <sqy99gy1ir....@lambda.jcn.srcf.net>, Christophe Rhodes <cs...@cam.ac.uk> wrote:
> But until someone comes up with a proposal dealing with whether FOO > is in a "mandatory tail-call" position in the following: > (let ((*print-length* 3)) > (foo))
If *print-length* is (following the usual convention) elsewhere declared special, then (foo) is clearly not in tail position, the restoration of *print-length* is.
In article <ey3n0pwsbo3....@cley.com>, Tim Bradshaw <t...@cley.com> wrote:
>And I think your take on `the Lisp approach' is basically completely >backward, at least as regards CL. The CL approach is to be pragmatic >- implement what can be agreed on and what can be seen to be >efficiently implementable and useful: don't implement stuff that >suddenly opens huge questions about what everything means, or whether >it can be implemented efficiently.
I agree with Tim here. The CL philosophy is to provide a library of high-level, proven facilities that are directly useful in applications, like hash tables and sequence functions. The Scheme approach is to provide basic mechanisms that can be used as building blocks for any programming paradigm. Common Lisp was intended for industrial programming, while Scheme was designed for academics. That doesn't mean they're only fitted for those environments, but their general approaches are based on the needs of those different types of uses.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
* Tim Josling | I am wondering why there is no call/cc in lisp. It seems to be potentially | useful.
Please get back to us when it is /actually/ useful.
| For example, in the book 'On Lisp', a significant part of this excellent | book seems to consists of reinventing various cut down versions of | call/cc.
Well, duh.
| (Call/cc is a way to save the current state of the program in a | variable. You can use the variable later on onto resume processing at | that point. It can be used for coroutines, exception handling, | nondeterministic search, etc.)
None of us know Scheme at all, so thanks for this lecture.
| To my naive point of view this seems to be contrary to the usual lisp | approach.
In your next life, learn a real Lisp before Scheme. This will change what you consider "usual" as well as actually help grasp a hell of lot more than you do now.
| Three possibilities as to why call/cc is not in lisp occur to me: | | 1. For some reason it is not seen as useful. But to me it seems useful.
That is because you have yet to learn how useful the Common Lisp constructs are. A common affliction of Scheme users is to believe that their ignorance of Common Lisp gives them a right to tell people about Scheme, which they know. This is actually nuts.
| 2. It is too hard to implement efficiently - period. I don't know enough | about implementing functional languages to say for sure, though it does | look like it might be a challenge to implement e.g. maybe you need to | copy the stack.
You do no implement languages with call/cc with ordinary stacks. Stacks are normally used to contain call frames. This works well because calls are strictly hierarchical. With call/cc, this is no longer true, so call frames need to be allocated from the heap and garbage-collected instead of the stack memory being trivially reusable.
| 3. It can be implemented efficiently in scheme, but is too hard to | implement efficiently in lisp. I can't see any reason why this would be | the case. Lisp is bigger than scheme but the core of the language does | not look that much bigger to me.
Do you actually believe this nonsense to be true?
| Can anyone shed any light on this? If someone wants to use this as a | springboard for a lisp versus scheme discussion, please start another | thread. (In my view lisp and scheme both have good reasons to exist.
I think both antibiotics and bacteria have good reason to exist, too.
-- Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.
Tim, you are well advised to ignore this nutjob of you want to learn and understand Common Lisp. Dorai is a known Scheme troll in this newsgroup and wastes no opportunity to tell us how superior Scheme is to actually getting work done.
-- Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.
Erik Naggum wrote: > * Tim Josling >> Three possibilities as to why call/cc is not in lisp >> occur to me: >> 3. It can be implemented efficiently in scheme, but is >> too hard to implement efficiently in lisp. I can't see >> any reason why this would be the case. Lisp is bigger >> than scheme but the core of the language does not look >> that much bigger to me.
> Do you actually believe this nonsense to be true?
He is asking about the reason.
That Tim is ignoring that call/cc is expensive in Scheme is another thing.
-- Jens Axel Søgaard
Attribute not to malice that which might be better explained by ignorance.
One possible answer is that it requires a complex stack structure. Do a web search for ``spaghetti stack''.
> It seems to be potentially > useful. For example, in the book 'On Lisp', a significant part of this > excellent book seems to consists of reinventing various cut down versions of > call/cc.
The question is whether actual Lisp software in production use contains such reinventions, or whether they were just whipped up for someone's amusement.
> (Call/cc is a way to save the current state of the program in a variable. You > can use the variable laterYour on onto resume processing at that point. It can be > used for coroutines, exception handling, nondeterministic search, etc.)
Yes; but that state remains saved even when the context in which it was created terminates; you can jump in and out of continuations. Each continuation is in fact a nearly a whole thread, requiring a chunk of stack space.
> The lisp approach seems to be to provide specific features for the common uses > of call/cc, such as exception handling. To my naive point of view this seems > to be contrary to the usual lisp approach. Normally you would expect to have a > very general facility, with macros/special forms used to provide specialised > versions. An example of this approach would be the iteration facilities which > can be constructed from goto and recursion, but are much more convenient.
But the difference is that GO doesn't have a whole facet of functionality that is ignored by iterative constructs built on top of it. It is used in its simple entirety to build up these higher level control mechanisms.
On the other hand, you do not need call/cc in its entirety to implement conditions.
How conditions work is that the program is suspended to search for a handler. The handler is called, and then that handler can execute a non-local exit somewhere, by invoking a restart, or other mechanism. At that point, the stack is unwound. Restarting is possible because a condition does not automatically unwind; when the handler is invoked, all the dynamic context is still there, so invoking a restart is nothing more than a non-local exit up through the point where the condition was signaled to some enclosing restart.
So as you can see, it can all be done with a simple stack structure; an implementation based on continuations would just generate useless garbage.
> Three possibilities as to why call/cc is not in lisp occur to me:
> 1. For some reason it is not seen as useful. But to me it seems useful.
Here is a consideration: most modern implementations of Common Lisp have threads! One way to look at continuations is that they are just a very low level mechanism by which the programmer can explicitly juggle multiple contexts. Threads are a simpler, higher level abstraction than continuations. For one thing, you don't need to save and restore your own context when switching between threads. This is really what dynamic-wind is all about; setting up some context and tearing it down upon entering and leaving a continuation. That's what threads are for so you don't have to juggle! When dispatched, your thread continues magically, all by itself, at the point where it was last suspended.
In article <sqy99gy1ir....@lambda.jcn.srcf.net>, Christophe Rhodes <cs...@cam.ac.uk> wrote:
>But until someone comes up with a proposal dealing with whether FOO >is in a "mandatory tail-call" position in the following: > (let ((*print-length* 3)) > (foo))
*print-length* being a special variable, right? Then, the call to foo is not in a tail-call position.
The other common objection I've heard is that when you trace a procedure that calls itself tail-recursively, the tail-calls cease to be tail-calls. That would be precisely correct and expected.
Tail-call elimination (TCE) only eliminates tail-calls. It obviously cannot and should not eliminate non-tail calls (what does that mean anyway? [1]). In cases where what "looks like" a tail-call but really isn't, TCE won't eliminate it, but so wouldn't a non-TCE scenario either, so you're losing nothing.
[1] That said, I do know of a rather academic paper from the early 1980s that treats getting something like special variables to not interfere with tail-calls, but it may not be of interest here.
>[ bearing in mind that FOO could end up throwing an error, putting you > into the debugger, where complex restarts may be available ] >and sundry other issues, then I think describing people who don't >actively work towards implementing more tail-call elimination by >implication as "unreasonable" is a little bit rich.
Actually I was using "voices of reason" quite literally, not as a synecdoche for reasonable individuals. The effect of a recent re-reading of Julian Jaynes, I guess. Let's not manufacture an offense where none was intended.
To clarify: I too doubt that TCE will become part of CL. In a hypothetical hierarchy however, I would class adding call/cc to CL to be even lower than adding TCE. To reiterate my answer to the OP, I do think that adding call/cc to CL would be extremely low-priority and have minimal (or at least non-worthwhile) payoff. IOW: while both TCE and call/cc are unlikely, call/cc is unlikelier. People also have a better understanding of TCE than call/cc, and in languages that have both, tend to use TCE oftener. Hence my relativizing.
* Dorai Sitaram | *print-length* being a special variable, right? Then, the call to foo is | not in a tail-call position.
This is not as obvious as you think, either. The unwinding that would take place upon a return may well include special variable unbinding and unwind-protect execution so a call to a function inside both may well be able to inherit the call frame of the caller. The smart way to ensure that special variables are unbound and unwind-protect forms are always run is to arrange for the function to return to a system function that does the necessary clean-up. When you do this, neither special bindings nor unwind-protect forms would stand between you and tail-call merging.
| [1] That said, I do know of a rather academic paper from the early 1980s | that treats getting something like special variables to not interfere | with tail-calls, but it may not be of interest here.
Perhaps it is already widely implemented.
| To clarify: I too doubt that TCE will become part of CL.
It is already part of the implementations under suitable optimization. Unlike the Scheme world, Common Lisp vendors are allowed to be smarter than the specification.
| IOW: while both TCE and call/cc are unlikely, call/cc is unlikelier.
Perhaps you should try to study reality a little? Or is that unlikely?
-- Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.
* Dorai Sitaram wrote: > Tail-call elimination (TCE) only eliminates tail-calls. > It obviously cannot and should not eliminate non-tail > calls (what does that mean anyway? [1]). In cases > where what "looks like" a tail-call but really isn't, > TCE won't eliminate it, but so wouldn't a non-TCE > scenario either, so you're losing nothing.
In order to add TCE *to the language definition* you have to specify *in the definition* all the places that are in tail position - It's not enough to say `we expect tail calls to be eliminated'. Given the number of WITH-x style constructs in CL and the many possible implementation techniques, this is probably rather a lot of work, and it's probably not possible to arrive at other than a ludicrously conservative definition without rendering several implementations *which currently do TCE* non-conforming.
The current situation is that almost all implementations already eliminate tail calls in many cases: the difference between that and having them specified in the language is mostly just spending a whole lot of money, and rendering some implementations that are currently conforming non-conforming.
In article <ey3smznr57z....@cley.com>, Tim Bradshaw <t...@cley.com> wrote:
>In order to add TCE *to the language definition* you have to specify >*in the definition* all the places that are in tail position - It's >not enough to say `we expect tail calls to be eliminated'. Given the >number of WITH-x style constructs in CL and the many possible >implementation techniques, this is probably rather a lot of work, and >it's probably not possible to arrive at other than a ludicrously >conservative definition without rendering several implementations >*which currently do TCE* non-conforming.
If the standard were conservative, then I'd expect that most of these implementations would conform. After all, the standard would only specify the places where TCE is *required*; that wouldn't prohibit TCE in other places (just as the current standard, which doesn't require any TCE, does not prohibit these implementations that perform TCE).
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Pascal Costanza <costa...@web.de> writes: > Tim Josling wrote: > > I learned scheme first and now I am moving to lisp. I am wondering > > why there is no call/cc in lisp. It seems to be potentially
> > useful. For example, in the book 'On Lisp', a significant part of this > > excellent book seems to consists of reinventing various cut down versions of > > call/cc.
> The standard argument I have read several times is that call/cc turned > out to be too powerful and is hard to use correctly. For example, I > recall reading a paper that formally proved that continuations and > exception handling are _not_ compatible. If you are interested I can > try to find out again which paper this was.
If I recall correctly, the `proof' was not fully general.
[ This is a terminology gripe and a request for different language usage]
d...@goldshoe.gte.com (Dorai Sitaram) writes: > Tail-call elimination (TCE) only eliminates tail-calls. > It obviously cannot and should not eliminate non-tail > calls (what does that mean anyway? [1]). In cases > where what "looks like" a tail-call but really isn't, > TCE won't eliminate it, but so wouldn't a non-TCE > scenario either, so you're losing nothing.
I detest the usage of the term Tail Call _Elimination_. I don't know how old it is, and it seems to be as perennial as the "lisp is big and slow" myth. Tail calls are never "eliminated" (as in turned into nothing), they are changed into something else (as in changed from a call to a jump). Using the word "elimination" causes confusion. [I suppose that a tail call could be eliminated if the compiler could prove that the called function returns exactly the same value as the caller and has no side effects, but that kind of "tail-call-elimination" would be less interesting than its greater and more general category of "call-elimination", and is not what we're discussing here.]
There are several ways to say what is being meant here in a more accurate or less confusing way. "Tail Call Optimizaton" is perfectly good, as is "Tail Merging" (the former is more descriptive, and the latter is self-defining because it has no confusing predefinitions).
You might object to this request based on your own definition of "elimination". However, my contention is that it is confusing to others, and given alternatives, should not be used.
Barry Margolin <bar...@genuity.net> writes: > In article <ey3smznr57z....@cley.com>, Tim Bradshaw <t...@cley.com> wrote: > >In order to add TCE *to the language definition* you have to specify > >*in the definition* all the places that are in tail position - It's > >not enough to say `we expect tail calls to be eliminated'. Given the > >number of WITH-x style constructs in CL and the many possible > >implementation techniques, this is probably rather a lot of work, and > >it's probably not possible to arrive at other than a ludicrously > >conservative definition without rendering several implementations > >*which currently do TCE* non-conforming.
> If the standard were conservative, then I'd expect that most of these > implementations would conform. After all, the standard would only specify > the places where TCE is *required*; that wouldn't prohibit TCE in other > places (just as the current standard, which doesn't require any TCE, does > not prohibit these implementations that perform TCE).
This depends on your definition of conservative. I believe that the standard _is_ conservative in not forcing implementations into a particular Tail Call Optimization practice. I also agree with Tim that many (if not all) of the native-code CL compilers already provide some sort of Tail Call Optimization under various circumstances.