3 ms·
>Having to rewrite all our for loops was not cool. You do realize that Scala doesn't have for loops, right?
by runT1ME 13y ago
>Having to rewrite all our for loops was not cool.
You do realize that Scala doesn't have for loops, right?
- anonymoushn 13y agoThat is probably why he had to rewrite them as while loops.
- saryant 13y agoOr tail-recursive functions which will be transformed into loops by the compiler: http://stackoverflow.com/questions/1677419/does-scala-support-tail-recursion-optimization http://stackoverflow.com/questions/1677419/does-scala-suppor...
- anonymoushn 13y agoThis works until he wants something other than a single loop in his function's body, yes. It's probably best to use the @tailrec annotation as the second answer does, since if you're writing Scala you're probably targeting a godawful runtime that can't actually do TCO, and you'd be in a pile of trouble if you messed up and your compiler ended up not doing it either.
- bad_user 13y agoIf you need loops within loops, nothing stops you to have tailrec functions called within other tailrec functions. Any loop can be rewritten as a tailrec function and I prefer tailrec functions because it's easier to me to guard against invariants changing or to reason about branches or exit conditions. Plus with algebraic data-types, the compiler can warn you that you missed a branch. Etc... Also, the compiler does optimize plain for-loops on ranges. You can even have a macro that rewrites your nice looking for loop into a while expression. On mutually recursive tail calls, yes, the runtime doesn't have support. Because it misses support for TCO, you're ready to call the JVM "godawful"? Might consider that .NET's tailrec support was basically a guideline that didn't work on 64bits .NET up until .NET 4.0 [1] and it's still not optimized, having a rather significant performance hit versus normal function calls. For the JVM, a prototype for optimized tail recursive calls is in the works and given the attention that invokeDynamic received lately, I have no doubt it will be implemented for JDK 9 [2], especially given that people like Guy Steele are calling for it [3]. Either way, it's not so bad to implement mutually tail recursive calls by means of trampolines in Scala, especially given that you have an expressive type system at your disposal [4]. > you'd be in a pile of trouble if you messed up and your compiler ended up not doing it either TCO is considered an optimization, not a guarantee, so if you want it to do a TCO by contract, then an annotation makes sense, no? [1] http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11... [2] http://openjdk.java.net/projects/mlvm/subprojects.html http://openjdk.java.net/projects/mlvm/subprojects.html [3] http://i.imgur.com/5X3VwOy.png http://i.imgur.com/5X3VwOy.png [4] http://blog.richdougherty.com/2009/04/tail-calls-tailrec-and-trampolines.html http://blog.richdougherty.com/2009/04/tail-calls-tailrec-and...
- anonymoushn 13y ago> On mutually recursive tail calls, yes, the runtime doesn't have support. Because it misses support for TCO, you're ready to call the JVM "godawful"? Some JVMs such as Avian support this feature, so they may not be godawful. I haven't used them much, so I don't know. > For the JVM, a prototype for optimized tail recursive calls is in the works and given the attention that invokeDynamic received lately, I have no doubt it will be implemented for JDK 9 [2], especially given that people like Guy Steele are calling for it [3]. This is great to hear, thanks for telling me about it :) It sounds like I will have a better time in JVM-land next time, if I ever have a reason to go back. > TCO is considered an optimization, not a guarantee, so if you want it to do a TCO by contract, then an annotation makes sense, no? In JVM-land, this is the case, which is why I said one should be careful to use the annotation. I don't have a problem with using the annotation. I do have a problem with TCO not being guaranteed in the language spec (like Lua), or at least supported by popular runtime+compiler combinations (like C++).