X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?a=blobdiff_plain;f=damn.mdwn;h=9524086ab9dfb1b3c0ec56a4b732a8680a38359f;hb=2664d5fe30e878c4c6fb6f6ef7549dea0bf03582;hp=cd011344e1e9a9f1247a8bf8f408934a00788c5e;hpb=57e0ef044fcf3252575126e6ffbc2ac49445d0fc;p=lambda.git diff --git a/damn.mdwn b/damn.mdwn index cd011344..9524086a 100644 --- a/damn.mdwn +++ b/damn.mdwn @@ -248,7 +248,7 @@ It's not immediately clear how to do it with "undelimited" continuations, of the (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. @@ -276,6 +276,8 @@ If a block `...` never invokes a shift, then `(reset ...)` will evaluate just th Going back to the beginning, then. We start with: + (require racket/control) ; this tells Scheme to let us use shift and reset + (define damn (lambda () 'id)) We evaluate: @@ -295,20 +297,19 @@ Evaluating that gives us: Now to pair that with an affective side-issue content, we'd instead define `damn` as: - (require racket/control) ; this tells Scheme to let us use shift and reset (define damn (lambda () (shift k (cons (cons 'side-effect 'bad) (k 'id))))) And voila: -(reset (cons (cons 'the 'man) - (cons 'read - (cons 'the - (cons (damn) - 'book))))) + (reset (cons (cons 'the 'man) + (cons 'read + (cons 'the + (cons (damn) + 'book))))) evaluates to: - '((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. @@ -318,17 +319,17 @@ Ken's proposal 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.