Name: Anonymous 2005-12-21 8:09
Because I'm learning it, almost done through the tutorial, and it looks great.
;; version of `map' that shares as much state as it can with the original list.
(define (map/share f xs)
(if (null? xs) xs
(let ((a (car xs))
(d (cdr xs)))
(let ((a1 (f a))
(d1 (map/share f d)))
(if (and (eq? a a1) (eq? d d1)) xs
(cons a1 d1))))))
(struct zipper (cont value))
(define (list->zipper xs)
(reset (map/share (lambda (x)
(let-values (((change-node? new-val)
(shift k (zipper k x))))
(if change-node? new-val x)))
xs)))
(define (zipper-next z)
((zipper-cont z) #f #f))
(define (zipper-set z x)
((zipper-cont z) #t x))
(define (zipper-unzip z)
(if (zipper? z) (zipper-unzip (zipper-next z)) z))
(define lst '(1 2 3 4 5 6 7 8 9))
(define z (list->zipper lst))
(let* ((z (zipper-next z)) ; go to the second node.
(z (zipper-set z 10)) ; set it to 10.
(z (zipper-set z 100)) ; and set the third node to 100.
(xs (zipper-unzip z))) ; we're done, get the list.
(values xs ; '(1 10 100 4 5 6 7 8 9)
lst ; '(1 2 3 4 5 6 7 8 9)
(eq? xs lst) ; #f
(eq? (cdddr xs)
(cdddr lst)) ; #t, these nodes are shared with the original list
))