[REBOL] About CONTINUATIONS
From: robbo1mark:aol at: 19-Feb-2002 13:39
from the REBOL 1.x user guide .....
The catch function allows you to return to a specified point in a script using a method
called continuation. A continuation is a saved point in the flow of execution that can
be called and returned to at a later time. Think of it as a bookmark that saves your
location and current context. Continuations are first class. They can be stored in variables,
passed as arguments, and returned from functions. As such, they provide a powerful mechanism
for advanced scripting in REBOL — especially for handling operations such as exceptions.
To use catch you provide a symbol and a block:
catch symbol body
The symbol is used as the name for a new function which holds the continuation point.
This function becomes available within the context of the body block, where it can be
called to return to the point just after the catch. Think of it as a throw function if
you are familiar with that concept from other languages. It takes one argument: a value
which will be returned as the result of the catch.
print catch 'throw [
loop 100 [
if (random 10) > 5 [throw "hit"]
The symbol throw is used here as the name of the continuation function. When it is applied,
its argument is used as the return from its associated catch. In the above example, its
behavior is identical to a return function.
The function named by catch is local to the block passed to catch. However, there may
be times when you want to return from functions called outside the block. To do so, define
a word outside the context of the block to hold the continuation function.
rand-it: func [num] [
loop num [
if (random num) > (num / 2) [resume "hit"]
print catch 'throw [
Here the word resume is given the function value of throw and is used outside the block
as a non-local return to the catch.
With the indefinite extent concept discussed later, continuations can be preserved even
beyond the return point of the catch. If after the example above, you were to write the
you would return to the same point as before — just after the catch — and
the "test" string would be passed to the print function. Note that the entire context
of the catch is preserved. Here is another example:
times: func [num] [num * catch 'here [resume-times: :here 1]]
result: times 1
if result < 100 [resume-times (result * 3)]
In this example, the catch marks the return point within the function times. When the
resume-times function is applied, it passes a new value back to the multiplication. Notice
that even the return point from times is preserved! The assignment to result and print
result are all done again, because they follow the initial call to times.
........ end of snip ..........
I started using REBOL just on the cusp of the version 2.x changeover, Brian Hawley &
Daan Oosterveld did have old windows versions of REBOL 1.x but Iam not sure if they still
do or if they're even still on this list.
I've studied Continuations A LOT recently, albeit the Scheme CALL-WITH-CURRENT-CONTINUATION
( abreviated Call/cc ) type and although it appears the REBOL 1.x type of conitinuations
are not as powerful as Scheme
I THINK IT'S A SHAME REBOL lost these capabilities along with proper tail recursion.
If anybody wants to learn more about this then go to
http://www.scheme.com where Kent Dybvig has LOADS of information and literature about
continuations, proper tail recursion etc. as well as an excellent freely available Scheme
implmentation to experiment these with called PetiteChez Scheme. MZScheme also has these
capabilities and is GPL free software, MZScheme is the under the hood Scheme in the DR-Scheme
Stackless-Python also has continuations and proper tail recursion and is a patch to implement
these capabilities into regular Python.
If anybody needs anymore info or explanations or URL's etc. just let me know I've got
tonnes of literature on this here.