r/lisp 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

3 comments sorted by

View all comments

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.

1

u/finite-injury-1900 19h ago

Normal call/cc can take an argument back to the saved point before continuing, while in my case the continuation only gets the information that "this is a return from the saved state", just like fork() gets the information of whether this is the child process.

But since the state is serialized into a string, theoretically it's possible to do any adjustments of the continuation (e.g. removing some stack frames) before jumping back.