Merge branch 'master' of ssh://server.philosophy.fas.nyu.edu/Users/lambda/lambda
authorChris Barker <barker@omega.(none)>
Sat, 27 Nov 2010 04:42:52 +0000 (23:42 -0500)
committerChris Barker <barker@omega.(none)>
Sat, 27 Nov 2010 04:42:52 +0000 (23:42 -0500)
assignment8.mdwn
new_stuff.mdwn
zipper.mdwn

index 547db8e..7e358a8 100644 (file)
                        in loop ()
                        ;;
 
+
+2.     Here's another implementation of the same-fringe function, in Scheme. It's taken from <http://c2.com/cgi/wiki?SameFringeProblem>. It uses thunks to delay the evaluation of code that computes the tail of a list of a tree's fringe. It also involves passing continuations as arguments. Your assignment is to supply comments to the code, to explain what every significant piece is doing.
+
+       This code uses Scheme's `cond` construct. That works like this;
+
+               (cond
+                       ((test1 argument argument) result1)
+                       ((test2 argument argument) result2)
+                       ((test3 argument argument) result3)
+                       (else result4))
+
+       is equivalent to:
+
+               (if (test1 argument argument)
+                       result1
+                       (if (test2 argument argument)
+                               result2
+                               (if (test3 argument argument)
+                                       result3
+                                       result4)))
+
+       Some other Scheme details:
+
+       *       `#t` is true and `#f` is false
+       *       `(list)` and `'()` both evaluate to the empty list
+       *       `(null? lst)` tests whether `lst` is the empty list
+       *       `(pair? lst)` tests whether `lst` is a pair; if `lst` is a non-empty list, it will also pass this test; if `lst` fails this test, it may be because `lst` is the empty list, or because it's not a list or pair at all
+       *       `(car lst)` extracts the first member of a pair / head of a list
+       *       `(cdr lst)` extracts the second member of a pair / tail of a list
+       *       `(lambda () ...)` constructs a thunk
+
+       Here is the implementation:
+
+               (define (lazy-flatten tree)
+                 (letrec ([helper (lambda (tree tailk)
+                                 (cond
+                                   [(pair? tree)
+                                     (helper (car tree) (lambda () (helper (cdr tree) tailk)))]
+                                   [(null? tree) (tailk)]
+                                   [else (cons tree tailk)]))])
+                   (helper tree (lambda () (list)))))
+               
+               (define (stream-equal? stream1 stream2)
+                 (cond
+                   [(and (null? stream1) (null? stream2)) #t]
+                   [(and (pair? stream1) (pair? stream2))
+                    (and (equal? (car stream1) (car stream2))
+                         (stream-equal? ((cdr stream1)) ((cdr stream2))))]
+                   [else #f]))
+               
+               (define (same-fringe? tree1 tree2)
+                 (stream-equal? (lazy-flatten tree1) (lazy-flatten tree2)))
+               
+               (define tree1 '(((1 2) (3 4)) (5 6)))
+               (define tree2 '(1 (((2 3) (4 5)) 6)))
+               
+               (same-fringe? tree1 tree2)
+
+
index a081480..55c8cba 100644 (file)
@@ -4,4 +4,9 @@ Page for Chris and Jim to see what each other is working on, but hasn't necessar
 
 [[Week11]]
 
+[[Curry-Howard]]
+
+[[Zipper-Lists-Continuations]]
+
 [[Assignment8]]
+
index 618d5f0..edefb9d 100644 (file)
@@ -402,7 +402,9 @@ Using these fringe enumerators, we can write our `same_fringe` function like thi
 
 The auxiliary `loop` function will keep calling itself recursively until a difference in the fringes has manifested itself---either because one fringe is exhausted before the other, or because the next leaves in the two fringes have different labels. If we get to the end of both fringes at the same time (`next1 (), next2 ()` matches the pattern `None, None`) then we've established that the trees do have the same fringe.
 
-The technique illustrated here with our fringe enumerators is a powerful and important one. It's an example of what's sometimes called **cooperative threading**. A "thread" is a subprogram that the main computation spawns off. Threads are called "cooperative" when the code of the main computation and the thread fixes when control passes back and forth between them. (When the code doesn't control this---for example, it's determined by the operating system or the hardware in ways that the programmer can't predict---that's called "preemptive threading.") With cooperative threads, one typically yields control to the thread, and then back again to the main program, multiple times. Here's the pattern in which that happens in our `same_fringe` function:
+The technique illustrated here with our fringe enumerators is a powerful and important one. It's an example of what's sometimes called **cooperative threading**. A "thread" is a subprogram that the main computation spawns off. Threads are called "cooperative" when the code of the main computation and the thread fixes when control passes back and forth between them. (When the code doesn't control this---for example, it's determined by the operating system or the hardware in ways that the programmer can't predict---that's called "preemptive threading.") Cooperative threads are also sometimes called *coroutines* or *generators*.
+
+With cooperative threads, one typically yields control to the thread, and then back again to the main program, multiple times. Here's the pattern in which that happens in our `same_fringe` function:
 
        main program            next1 thread            next2 thread
        ------------            ------------            ------------