proper tail calls

Brendan Eich brendan at mozilla.org
Mon Jan 21 22:50:16 PST 2008


On Jan 21, 2008, at 8:12 PM, Maciej Stachowiak wrote:

> On Jan 18, 2008, at 10:49 PM, Brendan Eich wrote:
>
>> "If, in order make the presence of an explicit form convenient, we
>> have to add sugar for it as an additional form of expression-closure
>> -- "goto call-expr()" means "{goto call-expr();} -- I don't think   
>> it's the end of the world. I do think, at present, we're meandering
>> aimlessly towards a system that claims to provide a way to make tail
>> calls, but in which nobody can ever figure out where or when they're
>> actually getting tail calls. I don't think it'll be useful to ship
>> such a language."
>
> Is "goto" the only option being considered for how to identify tail
> position?

See http://bugs.ecmascript.org/ticket/323#comment:10 where precedent  
from other languages suggests alternatives such as "become" and "jump".

> It seems to me this could easily be confused with what
> "goto" means in languages like C, Pascal or C#.

It might, and at least one JS implementation has supported computed  
goto (to support a port of an old Adventure game, IIRC), but never mind.

> "return" might be a
> good choice of syntax if it weren't for the implicit conversion
> problem.

It would, indeed: return and yield would both then be low-precedence  
unary operators.

> How about something like "tailcall" or "tailreturn".

Or just "tail f(x, y)", Dave Herman's suggestion.

> Here is another thing I don't understand: if goto must flag runtime
> errors in cases where otherwise implicit type conversion would occur,
> then does that not itself break proper tail recursion (something has
> to hang around to do the typecheck on the actually returned type)? Or
> is the intent that it throws a runtime error before the call if it
> can't statically prove that return types match? Does that mean you can
> never goto an untyped function from one with a declared return type?

 From Graydon's comment at http://bugs.ecmascript.org/ticket/ 
323#comment:10

     * Let f be the function-value result of evaluating the callee  
portion of <CallExpression>
     * Let args be the result of evaluating the argument portion of  
<CallExpression>
     * Let S be the return-type of f
     * Let T be the return-type of the current activation
     * Confirm the dynamic typecheck S <* T, or throw TypeError
     * Replace the current activation with an activation of  
Function.apply(f,args)

So: no, yes, and yes.

The ticket and wiki'ed proposal and discussion pages are worth a  
read, or re-read.

/be



More information about the Es4-discuss mailing list