An argument against call/cc (2012)
okmij.org
okmij.org
I tried the "memory leak" tests in Chicken (4.9.1) using the CSI REPL. The only modification made to the example "gen-leak.scm" was uncommenting the (display ...) line in (print-stream ...).
The result with (print-stream #f (gen-stream ones)) was non-terminating production of "1", like an infinite loop, but it didn't run out of memory, even after running >10 minutes in a resource-constrained VM.
I'm not familiar enough with how call/cc is implemented in Scheme48 vs. Chicken to comment in detail, but I'm sure there are substantial differences. The Chicken site (http://call-cc.org) provides quite a bit of info about its own implementation.
(And another way to do it is to simply allocate all your function call frames on the heap to begin with and not have a stack. Then call/cc is essentially free, but you need a really good incremental garbage collector because now every function call conses.)
> (let ((x 0)) (list (call/cc (lambda (f) (set! x 1) (f 2))) x))
(2 0) localhost:~/oort/examples% ../oort callcc2.nl
2
1
as expected since Oort uses heap allocated activation records.The Oort program:
typedef continuation_t = fn (p: int32) -> void;
call_cc (fun: fn(k: continuation_t) -> void) -> int32
{
retval: int32;
fun (fn (v: int32) -> void {
retval = v;
goto current_continuation;
});
// If fun returns without calling the continuation,
// then just return 0
return 0;
@current_continuation:
return retval;
}
x: int32 = 0;
print call_cc (fn (k: continuation_t) {
x = 1;
k (2);
});
print x;