The last few days I have tried to recreate my implementation of callcc
for Moscow ML. My original (incomplete) implementation was lost last fall when my old laptop was stolen (or it is still lurking somewhere in mess which is my old backup system).
The code almost works. For example, the following code, which just ignores the continuation value k
:
3 + callcc (fn k => 2 + 1);
Gives 6
, as it should.
However, the following more interesting example, which actually uses the continuation value:
3 + callcc (fn k => 2 + throw (k, 1));
Gives 67299815
and not 4
. Ouch!
Likewise, given the following declaration of multiply
:
fun multiply ints = callcc (fn ret => let fun mult nil = 1 | mult (0::_) = throw (ret, 0) | mult (n::ns) = n * mult ns in mult ints end)
The expression:
multiply [1,2,3,4,0,5];
evaluates to 67299810
and not 0
. Double ouch!!
My guess is that I somehow mess things up when I restore the stack, and some pointer ends up on top of the stack. But I’m too tired to debug this futher tonight.
One nifty feature of my code (if I can get it to work) is that it is implemented using the Dynlib
library. Which means that no changes are needed to the original Moscow ML code, it is all in a seperate library.