git.fiddlerwoaroof.com
lazy-sequence.lisp
5bca9a11
 (in-package :data-lens.transducers)
 
 (defclass lazy-sequence ()
   ((%next :initarg :next :reader next)))
 (defun lazy-sequence (next)
   (make-instance 'lazy-sequence :next next))
 
 (defmethod reduce-generic ((seq lazy-sequence) (func function) init)
   (let ((next (next seq)))
     (loop for next-val = (funcall next)
           for acc = init then next-acc
           for next-acc = (when next-val (funcall func acc next-val))
           while next-val
           finally (return acc))))
 
 (defmacro repeating (v)
   `(lazy-sequence
     (lambda ()
       ,v)))
 
 (defun repeating* (v &key count)
   (lazy-sequence
    (if count
        (let ((iterations 0))
          (lambda ()
            (when (< iterations count)
              (prog1 v
                (incf iterations)))))
        (lambda ()
          v))))
 
 (defun iota (&key (start 0) (step 1) count)
   (lazy-sequence
    (funcall
     (compile nil
              `(lambda ()
                 (declare (optimize (speed 3) (debug 1) (safety 1)))
                 (let ((init ,start)
                       ,@(serapeum:unsplice (when count
                                              '(iterations 0))))
                   (declare (type (integer ,start
                                           ,(if count
                                                (+ start (* count step))
                                                '*))
                                  init)
                            ,@(serapeum:unsplice
                               (when count
                                 `(type (integer 0 ,count) iterations))))
                   (lambda ()
                     (declare (optimize (speed 3)))
                     (,@(if count
                            `(when (< iterations ,count))
                            '(progn))
                      (prog1 init
                        (incf init ,step)
                        ,@(serapeum:unsplice
                           (when count
                             '(incf iterations))))))))))))