Merge branch 'master' of ssh://server.philosophy.fas.nyu.edu/Users/lambda/lambda
[lambda.git] / assignment8.mdwn
index 547db8e..cdb32e8 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
+       *       `(lambda () ...)` constructs a thunk
+       *       there is no difference in meaning between `[...]` and `(...)`; we just sometimes use the square brackets for clarity
+       *       `'(1 . 2)` and `(cons 1 2)` are pairs (the same pair)
+       *       `(list)` and `'()` both evaluate to the empty list
+       *       `(null? lst)` tests whether `lst` is the empty list
+       *       non-empty lists are implemented as pairs whose second member is a list
+       *       `'()` `'(1)` `'(1 2)` `'(1 2 3)` are all lists
+       *       `(list)` `(list 1)` `(list 1 2)` `(list 1 2 3)` are the same lists
+       *       `'(1 2 3)` and `(cons 1 '(2 3))` are both pairs and lists (the same 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
+
+       Here is the implementation:
+
+               (define (lazy-flatten tree)
+                 (letrec ([helper (lambda (tree tailk)
+                                 (cond
+                                   [(pair? tree)
+                                     (helper (car tree) (lambda () (helper (cdr 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)
+
+