4 ms·
Wait, what? Kawa does tail call optimization just fine. And it's a JVM language. https://www.gnu.org/software/kawa/Restrictions.html https://www.gnu.org/softw
by SeanLuke 11y ago
Wait, what? Kawa does tail call optimization just fine. And it's a JVM language.
https://www.gnu.org/software/kawa/Restrictions.html https://www.gnu.org/software/kawa/Restrictions.html
- Volundr 11y agoThe --full-tail-calls flag is not on by default, partly because it is noticably slower (though I have not measured how much), and partly I think it is more useful for Kawa to be compilatible with standard Java calling conventions and tools. Well, for some definition of just fine. Well implemented TCO is a performance boost, not hit on most platforms. The lack of TCO built into the JVM means that JVM languages like Scala and Kawa generally have to roll their own on top of the JVM, resulting in a performance hit.
- SeanLuke 11y agoPerformance is irrelevant I think to the discussion. The claim is being made that Clojure and ABCL don't do full tail call elimination because of stack restrictions in the JVM. That sounded unlikely to me. Kawa does full tail call elimination and it's a JVM language. Hence, this claim can't be true, right?
- Turing_Machine 11y agoWell, if you ignore performance, all Turing-complete languages are identical, right?
- Guvante 11y agoKawa fakes it. The JVM doesn't support it so if you use a normal function call you don't get tail recursion. You could avoid calling functions and instead do your own stuff but that doesn't change the fact that the JVM doesn't support it. That is what they mean by performance, you lose performance because you can't do naked function calls in those cases. Since except mutual recursion (which is difficult to detect tail recursion for correctly) the benefit of tail recursion is a performance boost it is ignored when the cost of implementing it kills your performance.
- GFK_of_xmaspast 11y agoIf it's a performance hit, that's not much of an 'optimization'.
- hga 11y agoOriginally, though, it didn't. See the current language in the link you provided, emphasis added: Kawa now does general tail-call elimination, but only if you use the flag --full-tail-calls. (Currently, the eval function itself is not fully tail-recursive, in violation of R5RS.) The --full-tail-calls flag is not on by default, partly because it is noticably slower (though I have not measured how much), and partly I think it is more useful for Kawa to be compilatible with standard Java calling conventions and tools. Code compiled with --full-tail-calls can call code compiled without it and vice versa.
- SeanLuke 11y agoThe fact that it didn't originally is irrelevant. And the fact that you have to provide a flag because of performance is irrelevant. It still remains that Kawa appears to do full tail call optimization on the JVM. So it can't be that Clojure doesn't do it because the JVM doesn't permit it. So what's really going on here?
- reitzensteinm 11y agoPerformance isn't irrelevant to the question of "what's really going on here". If it costs too much at run time, Clojure absolutely should not implement it. Lack of TCO isn't that big of a deal.
- kuschku 11y agoKawa emulates it by adding overhead that interprets and replaces code with loops. Clojure is instead waiting for a solution on JVM-level.