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:
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.