proper tail calls

Anton van Straaten anton at
Thu Jan 24 10:07:16 PST 2008

Chris Pine wrote:
> Anton van Straaten wrote:
>> 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.
> Because of the language semantics, not the implicit/explicit issue.

It's a bit of both.  My point is just that an explicit annotation that's 
required to achieve tail calls, and not allowed elsewhere, will require 
more thinking in more places than would be the case otherwise.

>> 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.
> But this is the case anyway:  you have to be aware of when you're 
> relying on a tail call that might not actually be a tail call.

I agree that the situation can occur either way.  An optional 
annotation, such as Lars recently described, is a fine way to address 
this: if you know you need a tail call and are unsure of whether you're 
going to get one, annotate.  But I'm saying that a *required* annotation 
is undesirable.

>> At the same time, you can't use the annotation in the wrong place, or 
>> you'll also get an error.
> Well, as you point out, if you are relying on a tail call when you 
> aren't getting one, you *already* have an error.  

My point was mainly that with a required annotation, it is necessary to 
annotate everywhere you need a tail call, and you can't mitigate this 
requirement by using a strategy of "when in doubt, annotate", unless 
you're willing to deal with the resulting additional error messages.

> It *does* require more knowledge and care to depend on tail call 
> semantics in ES4 than in other languages.  This has nothing to do with 
> implicit vs explicit.

Even so, I believe that a required explicit annotation would make things 
worse, not better.

> The *problem* is not implicit vs explicit.  The problem is the language 
> semantics making tail calls not obvious.

An optional assertion-style annotation would give programmers a way to 
address this without getting in their way when they don't they need it.

If the language semantics are such that you end up having to use the 
optional annotation on every tail call anyway, then my argument would 
fail.  But I suspect that it's more likely that programmers will be fine 
using the annotations a little like parentheses are often used in 
expressions: you put them in either for readability or when you're not 
sure of the precedence rules, but otherwise leave them out where you can.

>> 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.
> :P  You could make the same argument about any kind of error checking, 
> couldn't you?  

I don't think so.  Part of the problem is that a required annotation 
isn't just an error check, it's an instruction that affects semantics. 
If it were just an error check, i.e. an assertion, it'd be fine.

> Finding errors earlier is better than later.

That's only unequivocally true if all other things are equal.  But I 
notice that ES4 doesn't require that all types be declared, for example, 
even though requiring that would find more errors earlier.


More information about the Es4-discuss mailing list