Paste number 60780: iterators

Paste number 60780: iterators
Pasted by: wybiral
2 months, 3 weeks ago
None
Paste contents:
Raw Source | XML | Display As
(defun all (func lst)
  "True if func evaluates true for all in lst"
  (if (not lst) t
      (and (funcall func (car lst))
           (all func (cdr lst))
)
)
)


(defun irange (start stop step)
  "Iterator for (start <= i < stop) incremented by step"
  (if (<= stop start) nil
      (cons start
            (lambda ()
              (irange (+ start step)
                      stop
                      step
)
)
)
)
)


(defun ifrom (i step)
  "Start at i, infinitely increase by step"
  (cons i (lambda () (ifrom (+ i step) step)))
)


(defun ilist (lst)
  "Iterate over list"
  (if (not lst) nil
      (cons (car lst)
            (lambda ()
              (ilist (cdr lst))
)
)
)
)


(defun imap (func iter)
  "Iterator, mapping over an iterator"
  (let ((i (car iter))
        (next (cdr iter))
)

    (if (not next) nil
        (cons (funcall func i)
              (lambda ()
                (imap func
                       (funcall next)
)
)
)
)
)
)


(defun ilimit (n iter)
  "Limit iteration to n elements"
  (let ((i (car iter))
        (next (cdr iter))
)

    (if (not next) nil
        (if (= n 0) nil
            (cons i
                  (lambda ()
                    (ilimit (- n 1)
                            (funcall next)
)
)
)
)
)
)
)


(defun ifirst (func iter)
  "Return the first element for which func is true"
  (let ((i (car iter))
        (next (cdr iter))
)

    (if (not next) nil
        (if (funcall func i) i
            (ifirst func (funcall next))
)
)
)
)


(defun iuntil (func iter)
  "Iterate until func returns true for element"
  (let ((i (car iter))
        (next (cdr iter))
)

    (if (not next) nil
        (if (funcall func i) nil
            (cons i
                  (lambda ()
                    (iuntil func
                          (funcall next)
)
)
)
)
)
)
)


(defun iwhile (func iter)
  "Iterate while func returns true, otherwise stop"
  (iuntil (lambda (x)
            (not (funcall func x))
)

          iter
)
)


(defun lmap (func iter)
  "Map an iterator to a list"
  (let ((i (car iter)) (next (cdr iter)))
    (if (not next) nil
        (cons (funcall func i)
              (lmap func
                     (funcall next)
)
)
)
)
)

  
(defun ifilter (func iter)
  "Iterator filtering iterator"
  (let ((i (car iter))
        (next (cdr iter))
)

    (if (not next) nil
        (if (funcall func i)
            (cons i
                  (lambda ()
                    (ifilter func
                             (funcall next)
)
)
)

            (ifilter func
                     (funcall next)
)
)
)
)
)


(defun ireduce (func iter)
  "Reduce an iterator"
  (let ((i (car iter))
        (next (cdr iter))
)

    (let ((iter2 (funcall next)))
      (let ((i2 (car iter2))
            (next2 (cdr iter2))
)

        (if (not next2)i
            (ireduce func
                     (cons (funcall func i i2)
                           next2
)
)
)
)
)
)
)


(defun isum (iter)
  (ireduce #'+ iter)
)


(defun ireverse (iter)
  "Create a reverse iterator"
  (ilist (reverse (lmap #'identity
                         iter
)
)
)
)



(defun ifor (func iter)
  "Do func on each in iter"
  (if iter
      (progn (funcall func (car iter))
             (ifor func
                       (funcall (cdr iter))
)
)
)
)


(defun izip (&rest args)
  "Zip iterators together, output as list of ith items"
  (labels ((get-args (lst)
             (if (not lst) nil
                 (cons (caar lst)
                       (get-args (cdr lst))
)
)
)

           (get-list (lst)
             (if (not lst) nil
                 (let ((next (funcall (cdr (car lst)))))
                   (if (not next) 'stop
                       (let ((tail (get-list (cdr lst))))
                         (if (eq tail 'stop) 'stop
                             (cons (cons (car next)
                                         (cdr next)
)

                                   tail
)
)
)
)
)
)
)

           (inner-izip (lst)
             (let ((next (get-list lst)))
               (if (eq next 'stop)
                   (cons (get-args lst)
                         (lambda () nil)
)

                   (cons (get-args lst)
                         (lambda () (inner-izip next))
)
)
)
)
)

  (inner-izip args)
)
)


(defun ilast (iter)
  "Iterate ENTIRE sequence, return last"
  (let ((next (funcall (cdr iter))))
    (if (not next) (car iter)
        (ilast next)
)
)
)


(defun ifib ()
  "Infinite Fibonacci iterator"
  (labels ((inner-ifib (a b)
             (cons a (lambda ()
                       (inner-ifib b
                                   (+ a b)
)
)
)
)
)

    (inner-ifib 1 1)
)
)


(defun iprimes ()
  "Infinite prime iterator"
  (labels ((inner (i found)
             (if (all (lambda (x)
                         (not (= (mod i x) 0))
)
found
)

                 (cons i (lambda ()
                           (inner (+ i 1) (append found (list i)))
)
)

                 (inner (+ i 1) found)
)
)
)

    (inner 2 nil)
)
)

This paste has no annotations.

Colorize as:
Show Line Numbers

Ads absolutely not by Google

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.