proper tail calls

Anton van Straaten anton at
Tue Jan 22 12:38:19 PST 2008

Neil Mix wrote:
>> Others argue that this syntactic penalty box means no one will use
>> PTC; the cursed view of tail calls and recursion will not fade away.
> Interesting -- I'd love to know more about why that is.  Dave  
> Herman's example in the ticket isn't so bad once the annotation is  
> placed on the function call.  If this is such a highly desired  
> feature, how is it that it will be shunned if given a light syntactic  
> overhead?

In functional languages, proper tail calls are something that just 
happen automatically (to varying degrees depending on the language), and 
programmers don't need to think about them most of the time, if at all.

If an annotation is required to achieve proper tail calls, it means that 
you have to be aware of when you're relying on a tail call, and remember 
to use the annotation, or you'll have runtime problems when you 
implicitly rely on tail call behavior that's not there.  Like most 
runtime problems, this could happen in some circumstances but not 
others, e.g. after your program is deployed, but not in testing.

At the same time, you can't use the annotation in the wrong place, or 
you'll also get an error.

So you have two additional classes of error that don't exist in 
languages with implicit tail calls, and it requires more knowledge and 
care to use tail calls than it does in languages where they are implicit.

I also find it a bit ironic that errors that result from forgetting to 
use the tail annotation are the same general class of errors that the 
annotation is ostensibly intended to guard against: cases where a tail 
call is expected, but doesn't happen.  It's not unlikely that requiring 
this annotation could create more instances of this bug than it 
prevents, with the amusing property that the bugs it creates are the 
exact kind it's intended to prevent.

This is the sort of thing that you see in low-level languages, like 
bytecodes or intermediate languages, where code is usually generated by 
machine, so the machine is doing the reasoning about which construct to 
use where.  C-- is an example of this, mentioned in ticket #323. 
However, such pickiness doesn't seem appropriate for a high-level 
language, if the intent is that tail calls are a feature to be used by 
human programmers.

I'm not aware of any high level language that has a feature like this. 
The other two examples mentioned in the ticket, Newsqueak and Aleph 
a.k.a. Afnix, are either experimental or with extremely small user 
bases, and their keywords relating to tail calls don't work in the above 
way.  If there's anything to be learned from them, it may be that a 
tail-calling construct might be useful if it *didn't* throw an error 
when used on a non-tail expression, since both of them appear to work 
that way.


More information about the Es4-discuss mailing list