From: Matthew D Swank
Subject: generic sequences and generators
Date: 
Message-ID: <pan.2006.11.11.18.10.56.762832@c.net>
I suppose in some ways generators or more suited to streams than
sequences, but I could not resist implementing generators to conform to
Christophe Rhodes' CLOS sequence extension to sbcl:
http://www-jcsu.jesus.cam.ac.uk/~csr21/(sequences.diff | sequences.tar.gz)

The generator implementation is here:  http://paste.lisp.org/display/29695.

;;The sequence function are lazy when possible.

;; For instance you can define fib as:
(defgenerator fib ()
  (luup fib ((a 0) 
             (b 1))
    (gen-progn
     (yield b)
     (fib b (+ a b)))))

;;or you can use subseq:
(defgenerator fib ()
  (yield 1)
  (yield 1)
  (gen-map #'(lambda (x y)
               (+ x y))
           (subseq (fib) 0)
           (subseq (fib) 1)))

;; with leaves
(defgenerator leaves (tree)
  (cond ((null tree)
         gen-nil)
        ((and (null (cadr tree)) (null (cddr tree)))
         (yield (car tree)))
        (t (gen-progn
            (leaves (cadr tree))
            (leaves (cddr tree))))))

;; same fringe can look like
(defun same-fringe (t1 t2 &optional (pred #'eql))
  (reduce #'(lambda (rest current)
              (and rest current))
          (gen-map pred
                   (leaves t1)
                   (leaves t2))
           :initial-value t))

;;or
(defun same-fringe (t1 t2 &optional (pred #'eql))
  (loop for ele1 being the elements of (leaves t1)
        for ele2 being the elements of (leaves t2)
	do (unless (funcall pred ele1 ele2) (return nil))
	finally (return t)))

The loop path is kind of verbose, but overall generic sequences are *super
sweet*

Matt
-- 
"You do not really understand something unless you can 
explain it to your grandmother." — Albert Einstein.