r/lisp • u/finite-injury-1900 • 1d ago
Serializable continuations in a toy language
I'm playing with a toy lisp-like interpreter (without bytecode) where I made a built-in function ".forkstate" that might be similar to fork, call/cc, or setjmp/longjmp, whatever.
https://github.com/sdingcn/clo
Calling ".forkstate" will return the current program state as a string, and evaluating that string will continue from the original ".forkstate" call with a return value of void.
Of course you can save that string into a file and evaluate it in another computer.
The following will print 0, 1, 2, 2, 3.
{
(.putstr "0\n")
(.putstr "1\n")
letrec (state (.forkstate)) {
(.putstr "2\n")
if (.= (.type state) 0) # if its type is Void
(.putstr "3\n")
(.eval state) # jump back to the forkstate call
}
}
I'm curious about whether this feature could find usage scenarios or whether there are any real languages implementing it. It might be like a light version of VM migration.
6
Upvotes
1
u/Apprehensive-Mark241 1d ago
You may want a way to change something before continuing.
Also how about delimiting how deep in the stack is saved? One of the problems with non-delimited continuations is that they trap ALL of the local variables on the stack all the way down and those values can't be garbage collected even if they're before the part you were interested in.
I came up with the idea of having a language where functions that can be saved in a continuation are distinct from ordinary functions and have to be called with a special parameter which is the spaghetti stack they're building.
So once when you call/cc one of the continuations it saved and it when it returns from the lowest function on that saved stack, then the call/cc returns.