Signed-off-by: Jim Pryor <profjim@jimpryor.net>
(define damn (lambda () (call/cc (lambda (k) (cons (cons 'side-effect 'bad) (k 'id))))))
(define damn (lambda () (call/cc (lambda (k) (cons (cons 'side-effect 'bad) (k 'id))))))
-The idea here is we capture the continuation that `(damn)` has when it gets evaluated. This continuation is bound to the variable `k`. We supply `'id` as an argument to that continuation. When the main, at-issue tree is all built, then we return a pair `'((side-effect bad) AT-ISSUE-TREE)`.
+The idea here is we capture the continuation that `(damn)` has when it gets evaluated. This continuation is bound to the variable `k`. We supply `'id` as an argument to that continuation. When the main, at-issue tree is all built, then we return a pair `'((side-effect . bad) AT-ISSUE-TREE)`.
However, this doesn't work. The reason is that an undelimited continuation represents the future of the evaluation of `(damn)` *until the end of the computation*. So when `'id` is supplied to `k`, we go back to building the at-issue tree until we're finished *and that's the end of the computation*. We never get to go back and evaluate the application of `(cons (cons 'side-effect 'bad) <>)` to anything.
However, this doesn't work. The reason is that an undelimited continuation represents the future of the evaluation of `(damn)` *until the end of the computation*. So when `'id` is supplied to `k`, we go back to building the at-issue tree until we're finished *and that's the end of the computation*. We never get to go back and evaluate the application of `(cons (cons 'side-effect 'bad) <>)` to anything.
-(reset (cons (cons 'the 'man)
- (cons 'read
- (cons 'the
- (cons (damn)
- 'book)))))
+ (reset (cons (cons 'the 'man)
+ (cons 'read
+ (cons 'the
+ (cons (damn)
+ 'book)))))
- '((side-effect bad) ((the . man) . (read . (the . (id . book)))))
+ '((side-effect . bad) ((the . man) . (read . (the . (id . book)))))
So that's the straightforward way of repairing the strategy we used in class, without using `print`. We also have to switch to using delimited continuations.
So that's the straightforward way of repairing the strategy we used in class, without using `print`. We also have to switch to using delimited continuations.
Ken Shan pointed out a lovely way to get to the same end-point still using only undelimited continuations (`call/cc`).
Ken Shan pointed out a lovely way to get to the same end-point still using only undelimited continuations (`call/cc`).
-(let ((pragma
- ; An ordered pair whose first component is the assertion
- ; operator, a unary function, and whose second component
- ; is the meaning of "damn", a thunk.
- (call/cc (lambda (k)
- (cons (lambda (p) p)
- (lambda () (k (cons (lambda (p) (cons (cons 'side-effect 'bad) p))
- (lambda () 'id)))))))))
- (let ((assert (car pragma)) ; this binds assert to the first element of the pair pragma
- (damn (cdr pragma))) ; this binds damn to the second element of the pair pragma
- (assert (cons (cons 'the 'student) (cons 'read (cons 'the (cons (damn) 'book)))))))
+ (let ((pragma
+ ; An ordered pair whose first component is the assertion
+ ; operator, a unary function, and whose second component
+ ; is the meaning of "damn", a thunk.
+ (call/cc (lambda (k)
+ (cons (lambda (p) p)
+ (lambda () (k (cons (lambda (p) (cons (cons 'side-effect 'bad) p))
+ (lambda () 'id)))))))))
+ (let ((assert (car pragma)) ; this binds assert to the first element of the pair pragma
+ (damn (cdr pragma))) ; this binds damn to the second element of the pair pragma
+ (assert (cons (cons 'the 'student) (cons 'read (cons 'the (cons (damn) 'book)))))))
We won't do much to explain this. We'll just leave it for you to chew on.
We won't do much to explain this. We'll just leave it for you to chew on.