assign7 tweak
[lambda.git] / week4.mdwn
index daa1898..58d6bc3 100644 (file)
@@ -520,12 +520,11 @@ but really all we're in a position to mean by that are claims about the result
 of the complex expression semantically depending only on this, not on that. A
 demon evaluator who custom-picked the evaluation order to make things maximally
 bad for you could ensure that all the semantically unnecessary computations got
 of the complex expression semantically depending only on this, not on that. A
 demon evaluator who custom-picked the evaluation order to make things maximally
 bad for you could ensure that all the semantically unnecessary computations got
-evaluated anyway. We don't have any way to prevent that. Later,
-we'll see ways to *semantically guarantee* one evaluation order rather than
-another. Though even then the demonic evaluation-order-chooser could make it
-take unnecessarily long to compute the semantically guaranteed result. Of
-course, in any real computing environment you'll know you're dealing with a
-fixed evaluation order and you'll be able to program efficiently around that.
+evaluated anyway. We don't yet know any way to prevent that. Later, we'll see
+ways to *guarantee* one evaluation order rather than another. Of
+course, in any real computing environment you'll know in advance that you're
+dealing with a fixed evaluation order and you'll be able to program efficiently
+around that.
 
 In detail, then, here's what our v5 lists will look like:
 
 
 In detail, then, here's what our v5 lists will look like:
 
@@ -589,14 +588,29 @@ detail](http://okmij.org/ftp/Streams.html#enumerator-stream).
 >      that `5` is the outer/leftmost head of the list. That's not an efficient way
 >      to get the leftmost head.
 >      
 >      that `5` is the outer/leftmost head of the list. That's not an efficient way
 >      to get the leftmost head.
 >      
->      We could improve this by building lists as left folds when implementing them
->      as continuation-passing style folds. We'd just replace above:
+>      We could improve this by building lists as **left folds**. What's that?
+>      
+>      Well, the right fold of `f` over a list `[a;b;c;d;e]`, using starting value z, is:
+>      
+>                      f a (f b (f c (f d (f e z))))
+>      
+>      The left fold on the other hand starts combining `z` with elements from the left. `f z a` is then combined with `b`, and so on:
+>      
+>                      f (f (f (f (f z a) b) c) d) e
+>      
+>      or, if we preferred the arguments to each `f` flipped:
+>      
+>                      f e (f d (f c (f b (f a z))))
+>      
+>      Recall we implemented v3 lists as their own right-fold functions. We could
+>      instead implement lists as their own left-fold functions. To do that with our
+>      v5 lists, we'd replace above:
 >      
 >                      let make_list = \h t. \f2 z continue_handler abort_handler.
 >                              f2 h z (\z. t f2 z continue_handler abort_handler) abort_handler
 >      
 >      
 >                      let make_list = \h t. \f2 z continue_handler abort_handler.
 >                              f2 h z (\z. t f2 z continue_handler abort_handler) abort_handler
 >      
->      now `extract_head` should return the leftmost head directly, using its
->      `abort_handler`:
+>      Having done that, now `extract_head` can return the leftmost head
+>      directly, using its `abort_handler`:
 >      
 >                      let extract_head = \lst larger_computation. lst
 >                                      (\hd sofar continue_handler abort_handler. abort_handler hd)
 >      
 >                      let extract_head = \lst larger_computation. lst
 >                                      (\hd sofar continue_handler abort_handler. abort_handler hd)