43

As of Java 8, Java does not provide Tail-Call Optimization (TCO). On researching about it, I came to know the reason which is:

In JDK classes [...] there are a number of security sensitive methods that rely on counting stack frames between JDK library code and calling code to figure out who's calling them.

However Scala, which is based on JVM, has support for Tail-Call Optimisation. Scala does tail recursion optimisation at compile time. Why can't Java use the same approach?

PS: Not sure whether the latest version (Java 11 as of now) of Java now has TCO. Would be great if some who knows can share this also.

Notes:

  1. I know TCO is at backlog and is of lower priority but want to know why can't Java make changes in compile time similar to Scala.

  2. Java doesn't have tail call optimization for the same reason most imperative languages don't have it. Imperative loops are the preferred style of the language, and the programmer can replace tail recursion with imperative loops. (Source)

user207421
  • 305,947
  • 44
  • 307
  • 483
Rishabh Agarwal
  • 1,988
  • 1
  • 16
  • 33
  • From the video, I came to know that TCO can be done at runtime but for this, changes will be needed in JVM level. Any specific reason why Java does not use similar approach and make changes in javac – Rishabh Agarwal Nov 17 '18 at 19:48
  • Java doesn't have tail call optimization for the same reason most imperative languages don't have it. Imperative loops are the preferred style of the language, and the programmer can replace tail recursion with imperative loops. – Rishabh Agarwal Nov 17 '18 at 19:56
  • Yes it is. Wanted to share the info here. Isn't it the right way ? – Rishabh Agarwal Nov 17 '18 at 20:01
  • yes. much better. – Ousmane D. Nov 17 '18 at 20:24
  • [This blog entry](https://blogs.oracle.com/jrose/tail-calls-in-the-vm) about a "hard tail call" instruction for the JVM is from 2007. At the end of the comment section, Matthias Felleisen says *"This is a late comment but TCO in Java would be so great, why not revive the thread again? One common misunderstanding about TCO is due to the word 'optimization'. It is indeed a space optimization (don't use more space than goto, as Guy said in the 1970s) but a language should implement TCO in support of PROPER DESIGN. ...* – David Tonhofer Apr 16 '19 at 19:17
  • *...To wit, go through the OO design pattern books and inspect all the little patterns. Pick some -- say interpreter or composite -- and design your Java program accordingly. Then run a stress test and weep. Java blows up even if all the method calls are tail-recursive because it doesn't support TCO. Now do the same in PLT Scheme's class system and smile. It works -- for all inputs. See my ECOOP keynote (2004) for some more details -- Matthias* Implementing this in the JVM seems a pickle. – David Tonhofer Apr 16 '19 at 19:20
  • Issue [JDK-6804517 : Some languages need to be able to perform tail calls](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6804517) has been submitted 2009-02-12, updated 2018-10-05. Probably not for Java 13 (more like Java 9.3, amirite?) – David Tonhofer Apr 16 '19 at 19:21
  • 1
    The Java *compiler* has hardly any optimizations at all. The various JVMs. especially HotSpot, do all kinds of optimizations, but evidently not this one. Note that Scala is not used to compile the underlying JDK, which might explain it. – user207421 Jul 31 '20 at 10:07

2 Answers2

22

Why can't Java use the same approach ?

I can't say which approach will be used, but it's better-explained in Project Loom's proposal:

As adding the ability to manipulate call stacks to the JVM will undoubtedly be required, it is also the goal of this project to add an even lighter-weight construct that will allow unwinding the stack to some point and then invoke a method with given arguments (basically, a generalization of efficient tail-calls). We will call that feature unwind-and-invoke, or UAI. It is not the goal of this project to add an automatic tail-call optimization to the JVM.

As far as I've heard, work has not yet begun on tail calls, as Fibers and Continuations seem to currently be a higher priority.

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
13

I read a very nice blog post here about how to achieve tail recursion in Java: Knoldus blog post on Java tail recursion

However, the code on their blog doesn't compile so I created a small repo with their code but fixed the syntax so it compiles. Github repo with working code

Hope this is useful to someone, I found the ideas presented at the Knoldus blog post very interesting.

EDIT: actually I found out later that the ideas presented in the blog post are originally Venkat Subramaniam's. He discusses these subjects in his talk here.

Community
  • 1
  • 1
Jonck van der Kogel
  • 2,983
  • 3
  • 23
  • 30