Live data from Hacker News

What happened to proper tail calls in JavaScript? (2021)

mgmarlow.com

41–50 of 146 posts

Re: What happened to proper tail calls in JavaScript? (2021)

#41
post #31
post #30

Earlier quoted context omitted.

I'm guessing it's the same reason it doesn't have a reduce function, Guido loves loops

You what? https://docs.python.org/3/library/functools.html?highlight=r...

Grantparent is right. What you pointed to is in functools, a "functional" utility package in the stdlib, which has even more exotic stuff.

But Python doesn't have a reduce function as a primitive, and Guido and co discourage such uses. So much so, that Python 2 did have, and it was explicitly removed.

Re: What happened to proper tail calls in JavaScript? (2021)

#42
post #8

Worth reading why python doesn’t have it either http://neopythonic.blogspot.com/2009/04/tail-recursion-elimi...

Pretty good arguments in there: - TCO only addresses recursion that can easily be replaced by a loop - loosing stack frames makes debugging harder - its not just an optimization, as soon as code depends on it to not blow the stack its a required feature for all implementations - functional languages with no side effects need recursion, everyone else really doesn't Personally, I think TCO is bad in a similar way as as…

> TCO only addresses recursion that can easily be replaced by a loop

This is fundamentally false.

TCO addresses recursion that is implemented through the arbitrarily complex composition of functions, enabling one to define arbitrarily complex loop constructs through function composition.

There are many such interesting compositions that cannot be “unrolled” into a single high-level imperative for loop without essentially having to rewrite the code of all the functions being composed, including code that controls looping in interesting ways (e.g. automatically terminating on error, collecting all errors, parallelizing execution, etc.)

> It is an exception from the general mental model of how function calls work

It’s not, though — unless you have an incorrect mental model of how function calls work.

When calling a function, the return address is first pushed on the stack (or on some architectures, stored in a link register).

The target function returns from execution by popping the return address from the stack (or reading it from a link register), and jumping to that address.

When calling a function, if the call is in a tail position, the calling function can provide it’s original return address, and then jump to the target function it’s calling.

That’s how functions actually work. That’s the mental model.

> makes tooling much more complex

What significant complexity does TCO add to tooling, exactly?

> the alternative is just writing a loop

That’s simply not true. See first paragraph above.

Re: What happened to proper tail calls in JavaScript? (2021)

#43
post #32

I use recursion in JS when implementing generic trees/dags. I'm not worried at all about growing the stack because I use the language for UI stuff, where the depth of the trees is quite shallow and the data is small overall. I don't really know what the utility of TCO/proper tail calls would be. You already have UX constraints that nudge to avoid having a ton of stuff on the screen. As an example of where recursion o…

Javascript is also a very popular back-end language (Node JS)..

Re: What happened to proper tail calls in JavaScript? (2021)

#44
post #32

I use recursion in JS when implementing generic trees/dags. I'm not worried at all about growing the stack because I use the language for UI stuff, where the depth of the trees is quite shallow and the data is small overall. I don't really know what the utility of TCO/proper tail calls would be. You already have UX constraints that nudge to avoid having a ton of stuff on the screen. As an example of where recursion o…

The utility would be in the computational space, particularly when solving a problem functionally.

Re: What happened to proper tail calls in JavaScript? (2021)

#45
post #8

Worth reading why python doesn’t have it either http://neopythonic.blogspot.com/2009/04/tail-recursion-elimi...

Worth reading only if "because ignorance" is useful knowledge to you. In any case, you'd be better off starting at http://funcall.blogspot.com/2009/04/you-knew-id-say-somethin..., which tries to clear up some of the misconceptions Guido was laboring under at the time.

Re: What happened to proper tail calls in JavaScript? (2021)

#46

Earlier quoted context omitted.

Pretty good arguments in there: - TCO only addresses recursion that can easily be replaced by a loop - loosing stack frames makes debugging harder - its not just an optimization, as soon as code depends on it to not blow the stack its a required feature for all implementations - functional languages with no side effects need recursion, everyone else really doesn't Personally, I think TCO is bad in a similar way as as…

> TCO only addresses recursion that can easily be replaced by a loop This is fundamentally false. TCO addresses recursion that is implemented through the arbitrarily complex composition of functions, enabling one to define arbitrarily complex loop constructs through function composition. There are many such interesting compositions that cannot be “unrolled” into a single high-level imperative for loop without essenti…

> There are many such interesting compositions that cannot be “unrolled”.

You're arguing semantics, sure, you cannot mechanically transform code which relies on TCO into a loop. That is not the same as the parents point that TCO functions are isomorphic to loops. In a language without TCO you wouldn't ever find yourself in mess of composition of functions.

Re: What happened to proper tail calls in JavaScript? (2021)

#47
post #46

Earlier quoted context omitted.

> TCO only addresses recursion that can easily be replaced by a loop This is fundamentally false. TCO addresses recursion that is implemented through the arbitrarily complex composition of functions, enabling one to define arbitrarily complex loop constructs through function composition. There are many such interesting compositions that cannot be “unrolled” into a single high-level imperative for loop without essenti…

> There are many such interesting compositions that cannot be “unrolled”. You're arguing semantics, sure, you cannot mechanically transform code which relies on TCO into a loop. That is not the same as the parents point that TCO functions are isomorphic to loops. In a language without TCO you wouldn't ever find yourself in mess of composition of functions.

> You're arguing semantics, sure, you cannot mechanically transform code which relies on TCO into a loop.

TCO is how you mechanically transform recursive code into a loop.

> That is not the same as the parents point that TCO functions are isomorphic to loops.

That’s the same as claiming that manually copy-pasting the contents of functions into your code is isomorphic to calling those functions.

> In a language without TCO you wouldn't ever find yourself in mess of composition of functions.

Yes, that’s the point. There’s an entire class of useful constructions that cannot be implemented without TCO.

Re: What happened to proper tail calls in JavaScript? (2021)

#48
post #32

I use recursion in JS when implementing generic trees/dags. I'm not worried at all about growing the stack because I use the language for UI stuff, where the depth of the trees is quite shallow and the data is small overall. I don't really know what the utility of TCO/proper tail calls would be. You already have UX constraints that nudge to avoid having a ton of stuff on the screen. As an example of where recursion o…

I ran out of JS stack, walking the dependency graph of a big computation. Dependency graphs can be very deep relative to their overall size. It was a big pain to rewrite with an explicit stack of to-be-visited nodes.

TCO wouldn't have saved me, though. It just needs a big stack. Node defaults to just under 1 MB, which doesn't go very far.

Re: What happened to proper tail calls in JavaScript? (2021)

#49
post #43
post #32

I use recursion in JS when implementing generic trees/dags. I'm not worried at all about growing the stack because I use the language for UI stuff, where the depth of the trees is quite shallow and the data is small overall. I don't really know what the utility of TCO/proper tail calls would be. You already have UX constraints that nudge to avoid having a ton of stuff on the screen. As an example of where recursion o…

Javascript is also a very popular back-end language (Node JS)..

Yes, but even there it is typically used for stuff that leans towards front-end. People don't typically write databases and messaging systems in Nodejs.

I wonder about specific use cases where stack allocating recursion actually becomes an issue in the JS world.

Re: What happened to proper tail calls in JavaScript? (2021)

#50
post #46

Earlier quoted context omitted.

> TCO only addresses recursion that can easily be replaced by a loop This is fundamentally false. TCO addresses recursion that is implemented through the arbitrarily complex composition of functions, enabling one to define arbitrarily complex loop constructs through function composition. There are many such interesting compositions that cannot be “unrolled” into a single high-level imperative for loop without essenti…

> There are many such interesting compositions that cannot be “unrolled”. You're arguing semantics, sure, you cannot mechanically transform code which relies on TCO into a loop. That is not the same as the parents point that TCO functions are isomorphic to loops. In a language without TCO you wouldn't ever find yourself in mess of composition of functions.

This argument happens enough that it should be considered its own fallacy "appeal to the turing tarpit".

By this logic, we should still be using GOTO because if we were, you'd never need to use loops.

Proper tail calls exist because they make the logic of a lot of things easier and more simple to follow.

Post reply on HN