Put simply, a continuation is a representation of the rest of the program from a certain point, neatly wrapped up so that it can be called, and the rest of the program thereby resumed, at any time. One can think of continuation as a label in the program, calling the continuation being the same as issuing a goto to that label. The main difference then is that with a continuation all the variables are also restored to what they were when then the continuation was created. This means that a continuation (in Io) is a closure plus a jump destination. On top of that continuations in Io can also optionally accept parameters, in which case they are really gotos with parameters.
Don't worry if you don't understand the above immediatly, or if you don't know what closures are. I will try to explain what you need, and understanding closures, while not very hard, isn't necessary in any way.
01 function g(n): 02 y = n / 2; 03 return(y); 04 05 z = 1; 06 x = g(8); 07 print(x + z);This program will calculate the number 5 and print it on the screen, in a slightly roundabout fashion. We will now, step by step, walk through this small program, and piece by piece understand and convert it into a form in which we represent it as an example of continuation manipulation.
The program starts executing at line 5, assigning the value 1 to the variable z. Or, if we break this operation into even smaller pieces, it first evaluates the constant expression on the right hand side of the equal sign to the value 1, then assigns this value to the variable z. This way of expressing things is important so we'll write it down, but replace the word then with a semi colon.
evaluate the expression 1; assign the result to zWe can also express this like this:
1; -> zThe right arrow is read as assign to. This notation looks much like the original program but stresses the order in which things are executed. Next is how the entire program will look using this notation:
01 declare g(n): 02 n / 2; -> y; 03 return(y); 04 05 1; -> z; 06 g(8); -> x; 07 print(x + z);
So, to call a function you first need it available in form of it's name. In this case the function is called g and we call it with g(8). To be able to return from a function is a bit trickier. You need have a way to identify the place the function should return to, which doesn't have a name. So let's give this place a name in g so that we can jump back, let's call this place return. So now return is the name of the place to where the function should jump back after it has done it's deal. And on line 3, it does. Notice how this call to the place return looks exactly like the call g on line 6. This is what I like to call the return symmetry, returns are exactly like calls, they are both jumps.
To stress this g is rewritten slightly so that it shows that it's really a jump destination where the first thing that happens is that n is assigned the parameter value of the call:
declare g: -> n; n / 2; -> y; return(y);Notice how the start of g now looks exactly like the second half of line 6, where the jump to return takes the program. From here on we will write the assignment to n on the same line as the function declaration to stress that the assignment constitutes the parameters of g.
declare g: -> n return; n / 2; -> y; return(y);Now, this is starting to look a lot like Io code. In fact, the only differences between this code and Io code are syntactical. To transform this into Io code we need to change the calling syntax, until now we have used the classic mathematical syntax f(a,b,c), in Io the brackets are omitted and the same call is written f a b c. Furthermore, this code infix operators, the /, for division, and the /, for addition. Infix operators aren't available in Io and the code has to be rewritten as a regular function call instead. Also, for reason that will become clearer later, the call to print on line 7 will need to be rewritten with a new temporary to hold the result of the addition. Declarations in Io are terminated by a period (.) and the last statement needs no semicolon:
01 declare g: -> n return; 02 / n 2; -> y; 03 return y. 04 05 1; -> z; 06 g 8; -> x; 07 + x z -> t; 07 print t