(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)))