Hi,
First of all, thanks for the questions and interest! I never thought
anybody would care about this.
Yes, Factor's continuations are modelled after Scheme. Two words are
used to capture continuations:
callcc0
callcc1
Both have stack effect ( quotation -- ). They capture a continuation
right after the callcc call, push it on the stack, and call the
quotation. The quotation is then supposed to store the continuation
somewhere.
The capture continuation is in fact a quotation as well, so you can call
it with the 'call' primitive to restore execution.
The difference between callcc0 and callcc1 is the nature of the captured
continuation.
callcc0 simply restores execution to the point of continuation capture.
callcc1 restores execution and 'transfers' one parameter from the
current data stack to the restored data stack.
So callcc0 is like task switching, and callcc1 is like co-routines.
A non-trivial example can be found in the listener implementation (the
listener is the GUI interpreter). Continuations are used here because
GUI is event-driven ("push"), while the top-level interpreter is "pull".
I could just have written a new top-level interpreter with a "push"
model, but reusing the exact same code is much nicer.
When the top-level interpreter loop decides to read a line of input, it
calls a number of words which eventually delegate to the listener-readln
word.
The two key words in the listener implementation are:
: listener-readln* ( continuation -- line )
"listener" get
[ "factor.Cons" ]
"factor.listener.FactorListener"
"readLine" jinvoke ;
: listener-readln ( -- line )
reset-attrs [ listener-readln* suspend ] callcc1 ;
There is a lot of low level noise in these definitions, but they key
idea is that listener-readln captures the current continuation and calls
listener-readln*, which passes it to the GUI code, which is really a
thin layer over the Swing text pane. The GUI code is event-driven; so it
simply stores the continuation in an instance variable.
The "suspend" word clears all three stacks, effectively aborting the
interpreter.
Then later on when the ENTER event is received, the GUI pushes the input
line on the stack and calls the continuation. Since the continuation was
captured using callcc1, execution resumes at listener-readln, with the
new line of text on the restored stack. The top level interpreter
continues execution, completely unaware of what took place.
The game I'm working on uses continuations extensively for various
in-game events llike character interactions, waiting for user input, and
even as a multitasking engine in the implementation of big explosions,
that consist of multiple consecutive blasts.
Note that continuations cannot be compiled, and probably never will be,
due to limitations in the JVM. So they're not really suitable for use in
tight loops and such.
Chris Double wrote:
>You mention on the Factor website that the language supports
>continuations. Are there examples of usage? Are these continuations in
>the Scheme call/cc sense?
>
>Chris.
>
>