X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=week11.mdwn;h=b48dd5f410d314554c6fad96293592be0f855d96;hp=466c1e5bcfbf42df1e9579e0d50e53d353254e4c;hb=e34cd7e98c3004529c1ba28926e03d6a06bb7f45;hpb=ce6130150336db0e8cd1a6dd538bff45c9af7c6c diff --git a/week11.mdwn b/week11.mdwn index 466c1e5b..b48dd5f4 100644 --- a/week11.mdwn +++ b/week11.mdwn @@ -648,8 +648,40 @@ Okay, so that's our second execution pattern. ##What do these have in common?## +In both of these patterns, we need to have some way to take a snapshot of where we are in the evaluation of a complex piece of code, so that we might later resume execution at that point. In the coroutine example, the two threads need to have a snapshot of where they were in the enumeration of their tree's leaves. In the abort example, we need to have a snapshot of where to pick up again if some embedded piece of code aborts. Sometimes we might distill that snapshot into a datastructure like a zipper. But we might not always know how to do so; and learning how to think about these snapshots without the help of zippers will help us see patterns and similarities we might otherwise miss. +A more general way to think about these snapshots is to think of the code we're taking a snapshot of as a *function.* For example, in this code: + let foo x = + try + (if x = 1 then 10 + else abort 20) + 1 + end + in (foo 2) + 1;; + +we can imagine a box: + + let foo x = + +---------------------------+ + | try | + | (if x = 1 then 10 | + | else abort 20) + 1 | + | end | + +---------------------------+ + in (foo 2) + 1;; + +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. + +