I found languages with TCO even easier to implement FSM in: a state is simply a procedure, and going from one state to another is just a procedure call.
The difference is small, but once you start getting hairy state machines I have found that it leads to smaller mental overhead for me.
The same would be true for something like a recursive descent parser.
Function objects, including closures, can be serializable - they are in Erlang/Elixir. You can send a lambda/closure over to another node (on another machine) to execute. It's actually one of the basic building blocks of OTP.
Seems like trampolining would be useful to make it interruptible while still mostly preserving the ergonomics of viewing state transitions as procedure calls
Serializable closures (even serializable continuations) are available in a number of languages, including probably most often ones which also have TCO.
Tail Call Optimization, better called Tail Call Elimination. Haskell, OCaml, Erlang/Elixir, Scala with @tailrec, Scheme, Lua(!), most other functional languages.
Basically, if there's a call to a function B at the very end of function A, there's no need to create a new stack frame for the call to B - you can reuse the frame created for call to A. It both saves memory and improves performance. A special case is when A and B are both the same function, in which case we say A is tail-recursive.
The difference is small, but once you start getting hairy state machines I have found that it leads to smaller mental overhead for me.
The same would be true for something like a recursive descent parser.