author Jim Pryor Tue, 30 Nov 2010 23:42:07 +0000 (18:42 -0500) committer Jim Pryor Tue, 30 Nov 2010 23:42:07 +0000 (18:42 -0500)
Signed-off-by: Jim Pryor <profjim@jimpryor.net>

index c6b5f45..a7eccfc 100644 (file)
@@ -416,16 +416,6 @@ we can imagine a box:

and as we're about to enter the box, we want to take a snapshot of the code *outside* the box. If we decide to abort, we'd be aborting to that snapshotted code.

and as we're about to enter the box, we want to take a snapshot of the code *outside* the box. If we decide to abort, we'd be aborting to that snapshotted code.

-<!--
-# #require "delimcc";;
-# open Delimcc;;
-# let reset body = let p = new_prompt () in push_prompt p (body p);;
-val reset : ('a Delimcc.prompt -> unit -> 'a) -> 'a = <fun>
-# let foo x = reset(fun p () -> (shift p (fun k -> if x = 1 then k 10 else 20)) + 100) in (foo 1) + 1000;;
-- : int = 1110
-# let foo x = reset(fun p () -> (shift p (fun k -> if x = 1 then k 10 else 20)) + 100) in (foo 2) + 1000;;
-- : int = 1020
--->

What would a "snapshot of the code outside the box" look like? Well, let's rearrange the code somewhat. It should be equivalent to this:

What would a "snapshot of the code outside the box" look like? Well, let's rearrange the code somewhat. It should be equivalent to this:

@@ -496,6 +486,44 @@ We can get that by some further rearranging of the code:

And this is indeed what is happening, at a fundamental level, when you use an expression like `abort 20`.

And this is indeed what is happening, at a fundamental level, when you use an expression like `abort 20`.

+<!--
+# #require "delimcc";;
+# open Delimcc;;
+# let reset body = let p = new_prompt () in push_prompt p (body p);;
+# let test_cps x =
+         let snapshot = fun box ->
+                 let foo_result = box
+                 in (foo_result) + 1000
+         in let finish_value = fun start ->
+                 let value = start + 100
+                 in snapshot value
+         in if x = 1 then finish_value 10
+         else snapshot 20;;
+
+       let foo x =
+       +===try begin================+
+       |       (if x = 1 then 10    |
+       |       else abort 20) + 100 |
+       +===end======================+
+       in (foo 2) + 1000;;
+
+# let test_shift x =
+       let foo x = reset(fun p () ->
+               (shift p (fun k ->
+                       if x = 1 then k 10 else 20)
+               ) + 100)
+       in foo z + 1000;;
+
+# test_cps 1;;
+- : int = 1110
+# test_shift 1;;
+- : int = 1110
+# test_cps 2;;
+- : int = 1020
+# test_shift 2;;
+- : int = 1020
+-->
+
A similar kind of "snapshotting" lets coroutines keep track of where the left off, so that they can start up again at that same place.

These snapshots are called **continuations** because they represent how the computation will "continue" once some target code (in our example, the code in the box) delivers up a value.
A similar kind of "snapshotting" lets coroutines keep track of where the left off, so that they can start up again at that same place.

These snapshots are called **continuations** because they represent how the computation will "continue" once some target code (in our example, the code in the box) delivers up a value.