Scala is usually the language brought up as a counter argument here, but Scala has the same limitations as Clojure - the JVM can't do the TCO. Scala's compiler tries, with certain types of tail calls, to optimize via (I believe) a trampoline – it reduces those calls into a loop, so they are no longer a function call.
But, only certain types of calls (specifically, the last line of code in a recursive function must be a call to the hosting function) can be TCO in Scala. There is an annotation, scala.annotation.tailrec, which can be placed above a method you want to tail recurse.
@tailrec does not, however, "force" the compiler to do TCO – it simply forces compilation to fail if the method in question cannot be Tail Call Optimized. It's a developer hook for saying "I realize the compiler tries to do TCO where possible, but I require this method to be trampolined". If it can't be, you'll get a compilation error with details on why the TCO failed.
So @tailrec tells the compiler to compile this call to an unconditional jump.
And the x86, as a platform, does?
What, specifically, does the JVM do to make TCO more difficult than it would be in the machine code of your choice?
"It's complicated."
http://stackoverflow.com/questions/105834/does-the-jvm-preve...
OK, why do functions in the source language have to translate directly into methods at the JVM level? Purely for debugging?
If you want a runtime with proper tail calls, use a implementation which supports it.
Take standard class files and execute them on a runtime with proper tail calls. Done. Works.
Not allowing certain “optimizations” in security-sensitive contexts is perfectly fine. In fact, this is exactly what Avian, the CLR (and pretty much everyone else) is doing.
> Avian isn't a JVM; it's "designed to provide a useful subset of Java's features" and can run some Java code.
Now you're talking about legal aspects. Frankly, I'm not interested in discussing those.
Avian is a JVM for all practical purposes. If you disagree, please provide a test-case which runs on HotSpot but not on Avian.
Haha. As if the JVM needed proper tail calls to get owned every other week. :-)
Anyway, the discussion is pretty much moot, because "JVM" doesn't really refer to specific implementation. If one cares about proper tail calls, use an implementation which supports it.
Correction, the JVM that is made available by Oracle, and most people wrongly think it is the only one.
There are tons of JVM vendors out there.
> If one cares about proper tail calls, use an implementation which supports it.
Right?
Python has decided to place very conservative requirements on what an implementation's stack must be capable of. This might indicate a certain lack of ambition but it's a justifiable engineering tradeoff.
Essentially, your engineering tradeoff boils down to, "It's easier (for implementers) to omit TCO." That is actually a very reasonable and rational position, as simpler implementations are less likely to have bugs and have a lower creation cost. However, I still hold that the advantages of TCO outweigh the concern about its implementation. (Also, I do not believe that Python does place conservative requirements on an implementation's stack, as a conformant Python implementation must also implement generators; I regard this as roughly on par with TCO's complexity.)
I also should clarify that at this point, it's likely not reasonable to expect Guido or the Python community to ever turn around and decide to implement TCO, as the current engineering effort required to add TCO to all active implementations of Python is much larger in comparison to the engineering required to add it at an earlier stage. I regard this as a failure of the langauge design from the start, but having made their decision I don't fault the Python community for sticking to it.
You mean like gcc's -Werror? Or enabling asserts? Both of those seem useful to me.
If compilation warnings are given, then the responsible thing to do is to assume the program is invalid, at least in certain situations. Fix the code, avoid the warnings completely, and that's that.
There are remarkably few cases where compilation warnings can or should be ignored.