Simple tail calls
I created a Mozilla ticket in response and one of my comments there talks about the arguments.caller problem
arguments.caller is not defined by ES 3.0, right?
I think this feature is not helpful for efficient implementations, and it would be best to deprecate it.
I'm all for tail calls. I'd like to see implicit tail calls. Implicit tail calls would be necessary if tail calls are used in lambdas as there is no "return" statement in a lambda.
Personally I would prefer to have return statements in lambdas as well. Perhaps it is worth making a combined lambda + tail call proposal, given that the two features work well together.
On Sat, Dec 6, 2008 at 2:39 PM, Michael Day <mikeday at yeslogic.com> wrote:
Hi Peter,
I created a Mozilla ticket in response and one of my comments there
talks about the arguments.caller problem
arguments.caller is not defined by ES 3.0, right?
I think this feature is not helpful for efficient implementations, and it would be best to deprecate it.
It is also not defined by ES3.1-nonstrict. ES3.1-strict does better than deprecate it. It defines it (along with arguments.callee, <function>.caller,
and <function>.arguments) to throw an error.
Michael Day wrote:
Hi Mike,
What about
function f() { try { return g(); } finally { h(); } }
Good point! Is there any solution other than to say that try { } disables tail calls?
try blocks generally disable tail-call optimization in other language implementations.
It seems that the h() inside the finally could be return h(), which would make it a tail call.
Yes, but 'return g();' still wouldn't be.
function f() { with (o) return g(); }
Okay, so the with statement modifies the scope chain, which must be undone after the call to g(). Off the top of my head, I would say that this should still be a tail call unless enough implementers complain :)
Probably not worth the hassle given the usage frequency of 'with'.
On Dec 6, 2008, at 2:39 PM, Michael Day wrote:
Hi Peter,
I created a Mozilla ticket in response and one of my comments there talks about the arguments.caller problem
arguments.caller is not defined by ES 3.0, right?
Not even in ES1. Same for f.caller (for some active function f). The
caller hack used by folks including the TIBET team, but it should not
be standardized. Stack backtracing by a reflection API is the way to
go, if we can agree on such a thing (post 3.1).
I think this feature is not helpful for efficient implementations,
and it would be best to deprecate it.
arguments.caller is not in Firefox -- what browsers still support it?
f.caller is still around but it's pretty broken (can't handle
recursion). It's also subject to security checks that censor its value
depending on who is looking at whom.
From what I understand, if lambdas are supposed obey Tenent's principle, then they cannot have a return statement/expression. Wrapping an expression in a lambda must not change the meaning of the program. the following would need to be equivalent.
Right, I personally think this is unnecessary; functions don't follow this principle, after all.
I think it makes sense for expressions to have the same meaning, but not control flow statements when moved into a new execution context.
I think tail calls is really an es-discuss (i.e. not es3.x-discuss) topic so I've added that list.
Brendan commented to me about tail calls
esdiscuss/2008-July/006566
I created a Mozilla ticket in response and one of my comments there talks about the arguments.caller problem
bugzilla.mozilla.org/show_bug.cgi?id=445363
I'm all for tail calls. I'd like to see implicit tail calls. Implicit tail calls would be necessary if tail calls are used in lambdas as there is no "return" statement in a lambda.
Peter
I think tail calls is really an es-discuss (i.e. not es3.x-discuss) topic so I've added that list. Brendan commented to me about tail calls https://mail.mozilla.org/pipermail/es-discuss/2008-July/006566.html I created a Mozilla ticket in response and one of my comments there talks about the arguments.caller problem https://bugzilla.mozilla.org/show_bug.cgi?id=445363 I'm all for tail calls. I'd like to see implicit tail calls. Implicit tail calls would be necessary if tail calls are used in lambdas as there is no "return" statement in a lambda. Peter On Fri, Dec 5, 2008 at 4:17 PM, Michael Day <mikeday at yeslogic.com> wrote: > Hi, > > [Apologies in advance if this proposal has been made before] > > Idea: the JavaScript specification could require implementations to treat as > tail calls any ReturnStatement containing a CallExpression. > > function f() > { > return g(); // <-- tail call! > } > > ADVANTAGE: Very easy to specify and very easy to implement. > > It does not require tail calls for CallExpressions which occur outside of a > ReturnStatement, eliminating a big chunk of specification devoted to > figuring out exactly what is or isn't a tail call position. > > It does not require scanning through a function to identify tail positions, > so even the most basic interpreter operating directly on abstract syntax > trees could still implement them easily. > > I believe that this pattern would also be easier for users to learn and > harder to get wrong than tail calls which can occur outside of return > statements: > > ADVANTAGE: It makes tail calls explicit. > > Using "return f()" is as close as you can get to introducing a new keyword, > without introducing a new keyword. It makes it immediately obvious whether a > call is a tail call or not. EIBTI. > > ADVANTAGE: Explicit tail calls preserve correctness. > > The only point of requiring tail call optimisation rather than leaving it > optional is because the correctness of some code depends upon it. However, > implicit tail calls are easily lost as code changes. Consider a tail call > within a deeply nested block: > > function f() > { > if (cond) > { > if (cond) > { > ... > g(); // <-- supposed to be a tail call, but is it? > } > } > > minorCleanup(); // <-- oh no! someone added this! > } > > If tail calls use an explicit return, it is much harder to accidentally > break them, or overlook them. If tail calls are essential to ensure the > correctness of some code, they should be explicit in that code. > > NOTE: Does not preclude fancier optimisations. > > Implementations would be required to treat return calls as tail calls. > However, they would be free to treat other calls as tail calls as well, or > perform more complex optimisations such as introducing accumulator arguments > to transform code into tail-recursive form. > > DISADVANTAGES: None! Honestly, this proposal is made of 100% awesome :) > > It has minimal specification burden, minimal implementation burden, is > really easy to explain, teach, and learn, improves maintainability and helps > preserve correctness, while increasing speed and decreasing memory usage. > What's not to like? > > Best regards, > > Michael > > -- > Print XML with Prince! > http://www.princexml.com > _______________________________________________ > Es3.x-discuss mailing list > Es3.x-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es3.x-discuss >