Skip to content

Instantly share code, notes, and snippets.

@malisper
Last active August 29, 2015 14:17
Show Gist options
  • Save malisper/055848f4e593af5ca1b1 to your computer and use it in GitHub Desktop.
Save malisper/055848f4e593af5ca1b1 to your computer and use it in GitHub Desktop.
(defmacro iter (&body body)
(with-gensyms (iter-block accumulate start)
(handler-case
(macroexpand-dammit:macroexpand-dammit
`(block ,iter-block
(let ((,accumulate nil))
(macrolet ((while (condition)
`(unless ,condition
(return-from ,',iter-block
(nreverse ,',accumulate))))
(collect (thing &key into)
(if into
(signal 'accumulate-target :name into)
`(push ,thing ,',accumulate))))
(tagbody
,start
,@body
(go ,start))))))
;; handler
(accumulate-target (c)
(setf accumulate (name c))
(macroexpand-dammit:macroexpand-dammit
`(block ,iter-block
(let ((,accumulate nil))
(macrolet ((while (condition)
`(unless ,condition
(return-from ,',iter-block
(nreverse ,',accumulate))))
(collect (thing &key into)
`(push ,thing ,',accumulate)))
(tagbody
,start
,@body
(go ,start))))))))))
CL-USER> (let ((i 0))
(iter (while (< i 5))
(incf i)
(print acc)
(collect (+ 3 (* 4 i)) :into acc)))
NIL
(7)
(11 7)
(15 11 7)
(19 15 11 7)
(7 11 15 19 23) ; This is the return value, everything above was printed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment