3 ms·
Aha, but continuations are useful even without side effects. That's the beauty! (let ((p (call/cc (lambda (k) (cons 1 k))))) (print (car p)) (i
by jules 19y ago
Aha, but continuations are useful even without side effects. That's the beauty!
(let ((p (call/cc (lambda (k) (cons 1 k)))))
(print (car p))
(if (< (car p) 10)
((cdr p) (cons (+ 1 (car p)) (cdr p)))
'finished))
Can you understand what it does? No (set!) in sight!
Bonus:
(define (mark initial)
(call/cc (lambda (c)
(define (return value)
(c (cons value return)))
(cons initial return))))
(mark x) returns a pair of values. The car is x, the cdr is a (return) function. When you call (return y), the (mark x) call returns again, this time returning y instead of x. Here's an infinite loop example:
(let ((pair (mark 1)))
(let ((value (car pair)) (return (cdr pair))) ; unpack the pair
(print value)
(return (+ value 1)))) ; jump back to the (mark 1) call, this time returning value+1
Here's a Ruby implementation of mark:
def mark(initial)
callcc do |c|
ret = lambda{|value| c.call([value,ret])}
[initial, ret]
end
end
(I used ret instead of return because return is a Ruby keyword)
Example in Ruby:
value, ret = mark 1
puts value
ret.call(value + 1)