Tuesday, November 15, 2011

A simpler continuation example

Here's a simpler example using call/cc that needs function-continuation isomorphism to work, and how to handle that need in Factor.
(let ((x (call/cc (lambda (k) k))))
(x (lambda (ignore) "hi")))

In the code above, x is a continuation the first time around, and then a function the second time around (read below for a walkthrough), and it gets called both times with the same syntax. Factor doesn't implement call for continuations, so we need to "fix" it:
QUALIFIED: kernel
USE: locals

: call ( quot/cont -- ) dup continuation?
[ continue-with ] [ kernel:call ] if ; inline

FROM: scratchpad => call ;

[let [ ] callcc1 :> x
[| ignore | "hi" ] x call ]

On the first line, x is bound to the continuation about to bind something to x.
The second line then calls x with a lambda, which causes x to continue, which bounds the lambda to x. Now we've just run the first line a second time.
When we're back at the second line again, x is the lambda, and now it gets passed itself as an argument, which causes it to simply return the string "hi".

Continuations have a reputation of being useless, but I believe this is because they are a bit complicated to code with and that they're rarely implemented as they should be (with a global CPS transform), thus making them slow in most languages that implement them as an afterthought.

No comments:

Post a Comment