Wait what? Are we getting TCO or not with Loom?
Wait what? Are we getting TCO or not with Loom?
The security manager has to be removed first [1]
1. There is no way to rewrite this into loops by just modifying the insides of these functions.
2. The remedy, which is to transform these functions and everything that calls them into a giant loop causes lots of problems:
The code will become utterly unreadable (if you do this transform manually).
Modularity is completely broken and there's no sane way to expose these functions individually to external callers.
Also, even if you don't care about either of the above: your compiler's optimizer will probably choke on it (https://blog.reverberate.org/2021/04/21/musttail-efficient-i...).
Of lesser note, I don't believe I've ever come across mutually tail recursive functions, or the need for them, and although that may reflect my lack of experience in some areas, I guess it's not at all common? Maybe in the haskell world perhaps.
I'll read Steele's paper but introducing complexity only to struggle to delete that complexity is a strange approach
I find that recursive solutions are often easier to understand and change than iterative solutions, especially because you need less incidental state (and you can manage the state you have more cleanly), so I'm not sure what you mean by "introducing complexity only to struggle to delete that complexity". That would more aptly describe my experience with writing iterative versions of naturally recursive algorithms.
(I think you may have mistaken me for someone else; I didn't recommend Steele's paper.)
If goto is easily available in the high level language then creating a state machine is trivial I guess. If it's not then the compiler should be able to do TCO with jumps/gotos in the output asm or transpiled code (IIRC Bison's output uses gotos even though the input yacc rules clearly have none).
I continue to feel I'm missing something vital.
It's still painful, because whichever state you're in probably cares about different data. Some data only needs to exist during some states. Factoring states into separate functions means each gets its own scope, and can explicitly pass only data needed for the next state forward.
> If it's not then the compiler should be able to do TCO with jumps/gotos in the output asm or transpiled code
It's nice to be able to indicate explicitly to the compiler (and other developers!) that you expect tail calls to be optimized, rather than crossing your fingers and hoping that nobody else comes along later and accidentally adds something after the call. Scala optimizes tail recursion by default, but it also has a `tailrec` annotation that causes the compiler to throw an error if it isn't able to respect that intent.
Reminds me of a description of continuations as "gotos with parameters" which seems to be what you sort of want - I'll do some reading. Appreciated.
Well, had you read the link I posted in my reply to your question, you would have ;) Anyway, there are a some useful things that are much harder to do pleasantly and efficiently without it.
This is rather important, specially when coming from languages like Scheme that have TCO as part of the language specification compliance.