Despite the compiler complaining `Tail recursion o...
# arrow
p
Despite the compiler complaining
Tail recursion optimization inside try/catch/finally is not supported.
for a normal try/catch, it seems it does work when the try/catch is inlined a la
arrow.core.catch
or
arrow.core.recover
. The bytecode generated does seem to be a tail-recursive loop. arrow intensifies
y
Seems like an oversight. However, there is some broken behaviour when using
finally
because it gets triggered on the tail recursive call before it returns. Let me find the issue I submitted about this...
s
Yes, I've used that tricky many times in the past 😄 arrow intensifies Always thought it was an "intentional" side-effect inline + tailrec for cases
let
& co and operators like
Result.getOrElse
. Didn't know about KT-76868
a
Here's some explanation I once read somewhere about the
tailrec
messages in the Kotlin compiler: • the tailrec optimization happens in the IR phase, that is, after all the resolution/type checking/...; right before code generation • IR has a much closer view to the actual code being generated, because it already inlined functions, performs some optimization (like turning
for
in an index into a loop) • however, delaying "cannot perform tail recursion" to the IR phase is a no-go, since the "contract" in the compiler is that if the FIR (resolution/type checking/analysis) says something is correct, then IR can do its work • for that reason, the FIR phase has an approximation of whether using tail recursion is possible. It's very good, but it's impossible to be as tight as the IR phase, since it simply lacks some of the information • as a result, sometimes you see a warning about tailrec that can be suppressed and tail recursion is still optimized away