-
Notifications
You must be signed in to change notification settings - Fork 795
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
About Tail Call Optimization #340
Comments
As far as I know, closures prevent TCO because the enclosing the stack frame is reused/overwritten for TCO. Closures rely on the enclosing stack frame for variable lookup, which means it can't safely be destroyed. That said, none of this matters as it looks like implicit TCO will likely be removed in favor of explicit TCO. |
I think it definitely matters, because if closures prevent any sort of tail call technique, regardless of whether it's implicit or explicit, then this is definitely something that developers will have to be aware of. It's actually incredibly likely that functions people expect to be PTCd will have a closure over an outer scope, so this could be a huge caveat that would kill the usefulness of most PTC.
I don't think closure would be an issue in the general PTC case. Lemme illustrate: var bar = (function IIFE(){
function foo() { return 42; }
return function bar(x) {
if (x < foo()) return x;
return bar( x / 2 );
}
})();
bar( 608 ); // 38 Here, And now a counter example that definitely would be problematic for PTC and closure: function bar(x) {
if (x == 304) setTimeout( function inner() { console.log(x); }, 1000 );
if (x < 42) return x;
return bar( x / 2 );
}
bar( 608 ); // 38
// 1 second later:
// 304 Here, the closure that The good news is, I suspect that closure inside of a recursive function is exceedingly rare, whereas closure outside of its own scope is probably pretty common. |
@getify I agree that it is indeed rare to write inner closures like that in this context, explicit tail calls might make it clearer that tail calls are actually working, debugging implicit tail calls might not be the average programmer's thing i guess. @nzakas so your statement holds true then, although outer closures should work fine since they are not affected at all, closures inside the recursive call prevent stack frame reseting in tail calls since closures rely on the enclosing stack frame for variable lookup, which means it can't safely be destroyed. |
In your book, you have the following line:
I was discussing the issue on stackoverflow, and a few pointed out that this is not in the spec, and closures do not interfere with TCO since free variables of closures are stored on the heap. So a closure can live longer than its surrounding scope, where it was declared.
Can you explain why closures would prevent TCO, is there any reason?
I looked in the spec, and indeed i was unable to find any mention to closures in regards to the TCO topic. section (12.4 i believe).
The text was updated successfully, but these errors were encountered: