Skip to content

Instantly share code, notes, and snippets.

@lispm
Created September 29, 2017 23:12
Show Gist options
  • Select an option

  • Save lispm/19cf39a632282f2c7d1a851c946741e4 to your computer and use it in GitHub Desktop.

Select an option

Save lispm/19cf39a632282f2c7d1a851c946741e4 to your computer and use it in GitHub Desktop.
;see https://stackoverflow.com/questions/46496083/lazily-generating-prime-in-common-lisp/46497515#46497515
(defun divisor-in-list (n list)
(some (lambda (i)
(zerop (rem n i)))
list))
(defun primes ()
(let ((p (list 2))
(n 2))
(lambda ()
(case n
(2 (prog1 n (incf n)))
(otherwise
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
n)))))
(defun primes ()
(let ((p (list 2))
(n 2))
(lambda ()
(case n
(2 (incf n) 2)
(otherwise
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
n)))))
(defun make-prime-generator (&aux (p (list 2)) (n 2) f)
(labels ((init (function)
(setf f function))
(exit (result function)
(setf f function)
result)
(step ()
(funcall f))
(f2 ()
(incf n)
(exit 2 #'fn))
(fn ()
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
(exit n #'fn)))
(init #'f2)
#'step))
(defun make-prime-generator (&aux (p (list 2)) (n 2) f)
(flet ((init (function)
(setf f function))
(exit (result function)
(setf f function)
result)
(step ()
(funcall f)))
(labels ((f2 ()
(incf n)
(exit 2 #'fn))
(fn ()
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
(exit n #'fn)))
(init #'f2)
#'step)))
(defmacro gen-run (f-descriptions &key start)
(let ((§f (gensym "F"))
(§init (gensym "INIT"))
(§exit (gensym "EXIT"))
(§step (gensym "STEP")))
`(let (,§f)
(flet ((,§init (function)
(setf ,§f function))
(,§exit (result function)
(setf ,§f function)
result)
(,§step ()
(funcall ,§f)))
(labels (,@(loop for fd in f-descriptions
collect (destructuring-bind (name -> next &body body)
fd
(declare (ignore ->))
`(,name ()
(,§exit ((lambda () ,@body))
(function ,(if next next name)))))))
(,§init (function ,start))
(function ,§step))))))
(defun make-prime-generator (&aux (p (list 2)) (n 2))
(gen-run ((f2 -> fn
(incf n)
2)
(fn -> fn
(loop while (divisor-in-list n p)
do (incf n 2))
(push n p)
n))
:start f2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment