Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
Why Object-Oriented Languages Need Tail Calls (2011)
21–30 of 72 posts
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#22Earlier quoted context omitted.
But you can't ever turn it off if you rely on it for loops, which defeats the whole point.
You can turn it off, you just can't process large data sets, as you'd run out of stack space. But who wants to debug with large data sets?
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#23Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#24Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
We even already have a common keyword suitable for this: 'goto'.
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#25Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
Grumpy old man answer: because if you need "special syntax" to express the fact that your recursively defined function can technically be evaluated in constant stack space, you probably should be writing it as an iterative function to begin with.
The whole point about recursion as a software engineering paradigm is that it's a clearer way to express the problem and thus less likely to be mistakenly implemented. Special syntax is the opposite of clear.
Iteration ain't that hard either folks, and it has the notable advantage of mapping more obviously to the behavior of actual machines we use to execute our code.
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#26Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
This is how Clojure does it. https://clojuredocs.org/clojure.core/recur https://clojuredocs.org/clojure.core/trampoline
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#27Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
Clojure does exactly that:
(defn gcd [x y]
(if (zero? y)
x
(recur y (quot x y)))
You can also recur with TCO to an explicitly labelled point within the function (effectively creating an inner, anonymous function): (defn factorial [n]
(loop [n n, fac 1]
(if (zero? n)
fac
(recur (dec n) (* fac n)))))
As I understand it, this syntax was developed because of limitations of the JVM w/r/t TCO.Re: Why Object-Oriented Languages Need Tail Calls (2011)
#28Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
int factorial(int x) {
if (x > 1) return x * factorial(x-1);
else return 1;
}
to this: int factorial(int x) {
int result = 1;
while (x > 1) result *= x--;
return result;
}
(See http://ridiculousfish.com/blog/posts/will-it-optimize.html for other fun optimizations.)Re: Why Object-Oriented Languages Need Tail Calls (2011)
#29Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
> Why don't languages give tail calls their own syntax rather than making it an optimization? Clojure does exactly that: (defn gcd [x y] (if (zero? y) x (recur y (quot x y))) You can also recur with TCO to an explicitly labelled point within the function (effectively creating an inner, anonymous function): (defn factorial [n] (loop [n n, fac 1] (if (zero? n) fac (recur (dec n) (* fac n))))) As I understand it, this s…
This doesn't make sense. Tail calls don't need any virtual machine support whatsoever: they're translated into jumps by the compiler. The real problem is a lack of willingness to translate functions into anything other than JVM methods, because “compatibility“, but that is a political issue, not a technical one.
Re: Why Object-Oriented Languages Need Tail Calls (2011)
#30Why don't languages give tail calls their own syntax rather than making it an optimization? It seems like a lot of the arguments against tail calls boil down either 1) it's confusing when things go wrong and you weren't expecting stack frames to be optimized out or 2) it's hard to safely write tail-recursive code because a small change to the code or, worse, the compiler settings can make it stop being tail-recursive…
> Why don't languages give tail calls their own syntax rather than making it an optimization? Grumpy old man answer: because if you need "special syntax" to express the fact that your recursively defined function can technically be evaluated in constant stack space, you probably should be writing it as an iterative function to begin with. The whole point about recursion as a software engineering paradigm is that it's…