cps tweak
[lambda.git] / cps_and_continuation_operators.mdwn
index 0b0f25d..63a40a1 100644 (file)
@@ -276,11 +276,14 @@ The third example is more difficult to make work with the monadic library, becau
 
 <!-- FIXME -->
 
+Some callcc/letcc exercises
+---------------------------
+
 Here are a series of examples from *The Seasoned Schemer*, which we recommended at the start of term. It's not necessary to have the book to follow the exercises, though if you do have it, its walkthroughs will give you useful assistance.
 
 For reminders about Scheme syntax, see [here](/assignment8/) and [here](/week1/) and [here](/translating_between_ocaml_scheme_and_haskell). Other resources are on our [[Learning Scheme]] page.
 
-All of the examples assume the following preface:
+Most of the examples assume the following preface:
 
        #lang racket
 
@@ -327,13 +330,14 @@ Next, try to figure out what this function does:
                              [(null? l) (k 'notfound)]
                              [(eq? (car l) a) (cdr l)]
                              [(atom? (car l)) (cons (car l) (aux (cdr l) k))]
-                             ; what happens when (car l) exists but isn't an atom?
-                             [else (let ([car2 (let/cc k2 ; now what will happen when k2 is called?
-                                                 (aux (car l) k2))])
-                                     (cond
-                                       ; when will the following condition be met? what happens then?
-                                       [(eq? car2 'notfound) (cons (car l) (aux (cdr l) k))]
-                                       [else (cons car2 (cdr l))]))]))]
+                             [else
+                              ; what happens when (car l) exists but isn't an atom?
+                              (let ([car2 (let/cc k2 ; now what will happen when k2 is called?
+                                            (aux (car l) k2))])
+                                (cond
+                                  ; when will the following condition be met? what happens then?
+                                  [(eq? car2 'notfound) (cons (car l) (aux (cdr l) k))]
+                                  [else (cons car2 (cdr l))]))]))]
                     [lst2 (let/cc k1 ; now what will happen when k1 is called?
                             (aux lst k1))])
              (cond
@@ -341,7 +345,6 @@ Next, try to figure out what this function does:
                [(eq? lst2 'notfound) lst]
                [else lst2]))))
 
-
 Here is [the answer](/hints/cps_hint_3), but try to figure it out for yourself.
 
 Here is the hardest example. Try to figure out what this function does:
@@ -394,7 +397,11 @@ Here is [the answer](/hints/cps_hint_4), but again, first try to figure it out f
 Delimited control operators
 ===========================
 
-`callcc` is what's known as an *undelimited control operator*. That is, the continuations `outk` that get bound to our `k`s behave as though they include all the code from the `call/cc ...` out to *and including* the end of the program.
+Here again is the CPS for `callcc`:
+
+       [callcc (\k. body)] = \outk. (\k. [body] outk) (\v localk. outk v)
+
+`callcc` is what's known as an *undelimited control operator*. That is, the continuations `outk` that get bound into our `k`s include all the code from the `call/cc ...` out to *and including* the end of the program. Calling such a continuation will never return any value to the call site. (See the technique employed in the `delta` example above, with the `(begin (let/cc k2 ...) ...)`, for a work-around.)
 
 Often times it's more useful to use a different pattern, where we instead capture only the code from the invocation of our control operator out to a certain boundary, not including the end of the program. These are called *delimited control operators*. A variety of the latter have been formulated.