lists-to-contin tweaks
[lambda.git] / from_lists_to_continuations.mdwn
index a3ed6bf..170ae5d 100644 (file)
@@ -19,9 +19,7 @@ updated version.
 
 Expected behavior:
 
-<pre>
-t "abSd" ~~> "ababd"
-</pre>   
+       t "abSd" ~~> "ababd"
 
 
 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'):
 
-<pre>
-    t "aSbS" 
-        *
-~~> t "aabS" 
-          *
-~~> "aabaab"
-</pre>
+           t "aSbS" 
+               *
+       ~~> t "aabS" 
+                 *
+       ~~> "aabaab"
 
 versus
 
-<pre>
-    t "aSbS"
-          *
-~~> t "aSbaSb" 
-        *
-~~> t "aabaSb"
-           *
-~~> "aabaaabab"
-</pre>   
+           t "aSbS"
+                 *
+       ~~> t "aSbaSb" 
+               *
+       ~~> t "aabaSb"
+                  *
+       ~~> "aabaaabab"
 
 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
@@ -80,20 +72,19 @@ zipper `unzipped` and `zipped`; we start with a fully zipped list, and
 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).
 
-<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.
@@ -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']` 
-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>
@@ -150,11 +141,11 @@ be a function of type `char list -> char list`.  We'll call each step
 (or group of steps) a **continuation** of the recipe.  So in this
 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)`.
+the recipe below the horizontal line is the function `fun (tail : char
+list) -> 'a'::('b'::tail)`.
 
 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.
@@ -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:
 
-<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