cps tweaks
[lambda.git] / cps_and_continuation_operators.mdwn
index f619fc0..72b0034 100644 (file)
@@ -397,11 +397,13 @@ Here is [the answer](/hints/cps_hint_4), but again, first try to figure it out f
 Delimited control operators
 ===========================
 
 Delimited control operators
 ===========================
 
-Here again is the CPS for `callcc`:
+Here again is the CPS transform for `callcc`:
 
        [callcc (\k. body)] = \outk. (\k. [body] outk) (\v localk. outk v)
 
 
        [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.)
+`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. Also. if you've got a copy of *The Seasoned Schemer*, see the comparison of let/cc vs. "collector-using" (that is, partly CPS) functions at pp. 155-164.)
 
 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 these have been formulated. The most well-behaved from where we're coming from is the pair `reset` and `shift`. `reset` sets the boundary, and `shift` binds the continuation from the position where it's invoked out to that boundary.
 
 
 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 these have been formulated. The most well-behaved from where we're coming from is the pair `reset` and `shift`. `reset` sets the boundary, and `shift` binds the continuation from the position where it's invoked out to that boundary.
 
@@ -493,9 +495,9 @@ You can make the lambda evaluator perform the required CPS transforms with these
 
 You use these like so:
 
 
 You use these like so:
 
-*      [reset m] is `reset M` where `M` is [m]
-*      [shift k M] is `shift (\k. M)` where `M` is [m]
-*      and [abort M] is `abort M` where `M` is [m]
+*      [reset body] is `reset BODY` where `BODY` is [body]
+*      [shift k body] is `shift (\k. BODY)` where `BODY` is [body]
+*      and [abort value] is `abort VALUE` where `VALUE` is [value]
        
 There are also `reset` and `shift` and `abort` operations in the Continuation monad in our OCaml [[monad library]]. You can check the code for details.
 
        
 There are also `reset` and `shift` and `abort` operations in the Continuation monad in our OCaml [[monad library]]. You can check the code for details.