git.fiddlerwoaroof.com
Raw Blame History
(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))))))))))))