I'm a big fan of segmented stacks (or 'split stacks'), where stack frames are heap allocated, You can write recursive functions with less worry, and you get better tracebacks than TCO.
Go is the most popular language with this feature, to my knowledge: https://dave.cheney.net/2013/06/02/why-is-a-goroutines-stack-infinite
I'd assumed that LLVM didn't support this, but gollvm handles it fine! https://groups.google.com/g/golang-nuts/c/ivOZ-j6Zt2c/m/BUBX2Td9BgAJ
miniblog.
Related Posts
I'm a big fan of segmented stacks (or 'split stacks'), where stack frames are heap allocated, You can write recursive functions with less worry, and you get better tracebacks than TCO.
Go is the most popular language with this feature, to my knowledge:
Adding a tail-call optimisation macro (for self-calls) is a really fun lispy project: https://github.com/Wilfred/tco.el/blob/179b82cacbd59692e3c187b98f87a1f453923878/tco.el#L51-L63
Ironically, I've implemented TCO using a recursive function that can blow the stack.
Superb article on the history of parsers, what approaches are used in industry (mostly hand-written recursive descent!) and the expressiveness of parser combinators and PEG.