lists-to-contin tweaks
[lambda.git] / from_lists_to_continuations.mdwn
index f2e6989..8c84dfb 100644 (file)
@@ -6,7 +6,7 @@ to continuations is to re-functionalize a zipper.  Then the
 concreteness and understandability of the zipper provides a way of
 understanding and equivalent treatment using continuations.
 
 concreteness and understandability of the zipper provides a way of
 understanding and equivalent treatment using continuations.
 
-Let's work with lists of chars for a change.  To maximize readability, we'll
+Let's work with lists of `char`s for a change.  To maximize readability, we'll
 indulge in an abbreviatory convention that "abSd" abbreviates the
 list `['a'; 'b'; 'S'; 'd']`.
 
 indulge in an abbreviatory convention that "abSd" abbreviates the
 list `['a'; 'b'; 'S'; 'd']`.
 
@@ -19,9 +19,7 @@ updated version.
 
 Expected behavior:
 
 
 Expected behavior:
 
-<pre>
-t "abSd" ~~> "ababd"
-</pre>   
+       t "abSd" ~~> "ababd"
 
 
 In linguistic terms, this is a kind of anaphora
 
 
 In linguistic terms, this is a kind of anaphora
@@ -32,39 +30,33 @@ This deceptively simple task gives rise to some mind-bending complexity.
 Note that it matters which 'S' you target first (the position of the *
 indicates the targeted 'S'):
 
 Note that it matters which 'S' you target first (the position of the *
 indicates the targeted 'S'):
 
-<pre>
-    t "aSbS" 
-        *
-~~> t "aabS" 
-          *
-~~> "aabaab"
-</pre>
+           t "aSbS" 
+               *
+       ~~> t "aabS" 
+                 *
+       ~~> "aabaab"
 
 versus
 
 
 versus
 
-<pre>
-    t "aSbS"
-          *
-~~> t "aSbaSb" 
-        *
-~~> t "aabaSb"
-           *
-~~> "aabaaabab"
-</pre>   
+           t "aSbS"
+                 *
+       ~~> t "aSbaSb" 
+               *
+       ~~> t "aabaSb"
+                  *
+       ~~> "aabaaabab"
 
 versus
 
 
 versus
 
-<pre>
-    t "aSbS"
-          *
-~~> t "aSbaSb"
-           *
-~~> t "aSbaaSbab"
-            *
-~~> t "aSbaaaSbaabab"
-             *
-~~> ...
-</pre>
+           t "aSbS"
+                 *
+       ~~> t "aSbaSb"
+                  *
+       ~~> t "aSbaaSbab"
+                   *
+       ~~> t "aSbaaaSbaabab"
+                    *
+       ~~> ...
 
 Aparently, this task, as simple as it is, is a form of computation,
 and the order in which the `'S'`s get evaluated can lead to divergent
 
 Aparently, this task, as simple as it is, is a form of computation,
 and the order in which the `'S'`s get evaluated can lead to divergent
@@ -75,25 +67,24 @@ guarantees termination, and a final string without any `'S'` in it.
 
 This is a task well-suited to using a zipper.  We'll define a function
 `tz` (for task with zippers), which accomplishes the task by mapping a
 
 This is a task well-suited to using a zipper.  We'll define a function
 `tz` (for task with zippers), which accomplishes the task by mapping a
-char list zipper to a char list.  We'll call the two parts of the
+`char list zipper` to a `char list`.  We'll call the two parts of the
 zipper `unzipped` and `zipped`; we start with a fully zipped list, and
 zipper `unzipped` and `zipped`; we start with a fully zipped list, and
-move elements to the zipped part by pulling the zipped down until the
+move elements to the zipped part by pulling the zipper down until the
 entire list has been unzipped (and so the zipped half of the zipper is empty).
 
 entire list has been unzipped (and so the zipped half of the zipper is empty).
 
-<pre>
-type 'a list_zipper = ('a list) * ('a list);;
-
-let rec tz (z:char list_zipper) = 
-    match z with (unzipped, []) -> List.rev(unzipped) (* Done! *)
-               | (unzipped, 'S'::zipped) -> tz ((List.append unzipped unzipped), zipped) 
-               | (unzipped, target::zipped) -> tz (target::unzipped, zipped);; (* Pull zipper *)
-
-# tz ([], ['a'; 'b'; 'S'; 'd']);;
-- : char list = ['a'; 'b'; 'a'; 'b'; 'd']
-
-# tz ([], ['a'; 'S'; 'b'; 'S']);;
-- : char list = ['a'; 'a'; 'b'; 'a'; 'a'; 'b']
-</pre>
+       type 'a list_zipper = ('a list) * ('a list);;
+       
+       let rec tz (z:char list_zipper) = 
+           match z with
+           | (unzipped, []) -> List.rev(unzipped) (* Done! *)
+           | (unzipped, 'S'::zipped) -> tz ((List.append unzipped unzipped), zipped) 
+           | (unzipped, target::zipped) -> tz (target::unzipped, zipped);; (* Pull zipper *)
+       
+       # tz ([], ['a'; 'b'; 'S'; 'd']);;
+       - : char list = ['a'; 'b'; 'a'; 'b'; 'd']
+       
+       # tz ([], ['a'; 'S'; 'b'; 'S']);;
+       - : char list = ['a'; 'a'; 'b'; 'a'; 'a'; 'b']
 
 Note that this implementation enforces the evaluate-leftmost rule.
 Task completed.
 
 Note that this implementation enforces the evaluate-leftmost rule.
 Task completed.
@@ -131,8 +122,8 @@ to get there, we'll first do the exact same thing we just did with
 concrete zipper using procedures.  
 
 Think of a list as a procedural recipe: `['a'; 'b'; 'S'; 'd']` 
 concrete zipper using procedures.  
 
 Think of a list as a procedural recipe: `['a'; 'b'; 'S'; 'd']` 
-is the result of the computation `a::(b::(S::(d::[])))` (or, in our old
-style, `makelist a (makelist b (makelist S (makelist c empty)))`).
+is the result of the computation `'a'::('b'::('S'::('d'::[])))` (or, in our old
+style, `make_list 'a' (make_list 'b' (make_list 'S' (make_list 'd' empty)))`).
 The recipe for constructing the list goes like this:
 
 <pre>
 The recipe for constructing the list goes like this:
 
 <pre>
@@ -151,10 +142,10 @@ be a function of type `char list -> char list`.  We'll call each step
 context, a continuation is a function of type `char list -> char
 list`.  For instance, the continuation corresponding to the portion of
 the recipe below the horizontal line is the function `fun (tail:char
 context, a continuation is a function of type `char list -> char
 list`.  For instance, the continuation corresponding to the portion of
 the recipe below the horizontal line is the function `fun (tail:char
-list) -> a::(b::tail)`.
+list) -> 'a'::('b'::tail)`.
 
 This means that we can now represent the unzipped part of our
 
 This means that we can now represent the unzipped part of our
-zipper--the part we've already unzipped--as a continuation: a function
+zipper---the part we've already unzipped---as a continuation: a function
 describing how to finish building the list.  We'll write a new
 function, `tc` (for task with continuations), that will take an input
 list (not a zipper!) and a continuation and return a processed list.
 describing how to finish building the list.  We'll write a new
 function, `tc` (for task with continuations), that will take an input
 list (not a zipper!) and a continuation and return a processed list.
@@ -162,23 +153,23 @@ The structure and the behavior will follow that of `tz` above, with
 some small but interesting differences.  We've included the orginal
 `tz` to facilitate detailed comparison:
 
 some small but interesting differences.  We've included the orginal
 `tz` to facilitate detailed comparison:
 
-<pre>
-let rec tz (z:char list_zipper) = 
-    match z with (unzipped, []) -> List.rev(unzipped) (* Done! *)
-               | (unzipped, 'S'::zipped) -> tz ((List.append unzipped unzipped), zipped) 
-               | (unzipped, target::zipped) -> tz (target::unzipped, zipped);; (* Pull zipper *)
-
-let rec tc (l: char list) (c: (char list) -> (char list)) =
-  match l with [] -> List.rev (c [])
-             | 'S'::zipped -> tc zipped (fun x -> c (c x))
-             | target::zipped -> tc zipped (fun x -> target::(c x));;
-
-# tc ['a'; 'b'; 'S'; 'd'] (fun x -> x);;
-- : char list = ['a'; 'b'; 'a'; 'b']
-
-# tc ['a'; 'S'; 'b'; 'S'] (fun x -> x);;
-- : char list = ['a'; 'a'; 'b'; 'a'; 'a'; 'b']
-</pre>
+       let rec tz (z:char list_zipper) = 
+           match z with
+           | (unzipped, []) -> List.rev(unzipped) (* Done! *)
+           | (unzipped, 'S'::zipped) -> tz ((List.append unzipped unzipped), zipped) 
+           | (unzipped, target::zipped) -> tz (target::unzipped, zipped);; (* Pull zipper *)
+       
+       let rec tc (l: char list) (c: (char list) -> (char list)) =
+           match l with
+           | [] -> List.rev (c [])
+           | 'S'::zipped -> tc zipped (fun x -> c (c x))
+           | target::zipped -> tc zipped (fun x -> target::(c x));;
+       
+       # tc ['a'; 'b'; 'S'; 'd'] (fun x -> x);;
+       - : char list = ['a'; 'b'; 'a'; 'b']
+       
+       # tc ['a'; 'S'; 'b'; 'S'] (fun x -> x);;
+       - : char list = ['a'; 'a'; 'b'; 'a'; 'a'; 'b']
 
 To emphasize the parallel, I've re-used the names `zipped` and
 `target`.  The trace of the procedure will show that these variables
 
 To emphasize the parallel, I've re-used the names `zipped` and
 `target`.  The trace of the procedure will show that these variables