Unoptimizable recursion
A nested formation that calls itself in a tail position is turned
into a Java loop at transpile time: the compiler wraps the copies into
PhLoop and the calls into PhAgain, so a run
takes one object per step instead of one Java stack block per step.
The compiler recognises two tail positions, a branch of an
if. and the last step of a seq *:
[] > app
[n] > rec
if. > @
n.lt 1
0
^.rec (n.minus 1)
rec 5 > @
Every other shape runs as plain recursion, which is correct but deeper and slower, and the compiler says nothing about it. This lint says it, naming the reason it found. A self-call under an operation, for example, is not in a tail position, because the operation has work left to do after the call answers:
[] > app
[n] > rec
if. > @
n.lt 1
0
n.plus (^.rec (n.minus 1))
rec 5 > @
Rewrite such an object with an accumulator, the way
repeated was rewritten by hand, and the recursion becomes a
loop again.
Published on Fri Oct 2 12:30:33 UTC 2026.