Skip to content

Instantly share code, notes, and snippets.

@oranenj
Created February 22, 2010 23:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oranenj/311647 to your computer and use it in GitHub Desktop.
Save oranenj/311647 to your computer and use it in GitHub Desktop.
(defmacro generate-iter
"the init form is a vector of name/initval pairs"
[name initform has-item-expr item-expr move!-expr valueof-expr]
(let [args (vec (map first (partition 2 initform)))
inits (map second (partition 2 initform))]
`(letfn
[(~name ~args
(reify :as ~'this
~'Iter
(~'has-item [] ~has-item-expr)
(~'item [] ~item-expr)
(~'move! [] ~move!-expr)
~'Transient
(~'value-of
[]
(reify ~'Editable
(transient-of [~'sentry]
~valueof-expr)))))]
(iter-seq (~name ~@inits)))))
(defn filterx
[pred coll]
(generate-iter
iter [p pred, seq-cell (cell (sequence coll))]
;; has-item
(do
(loop [cc seq-cell]
(when (and (<< has-item cc) (not (pred (<< item cc))))
(recur (>> move! cc))))
(<< has-item seq-cell))
;; item
(<< item seq-cell)
;; move!
(do (>> move! seq-cell) this)
;; valueof... has 'sentry defined
(iter pred (make-cell sentry (sequence @seq-cell)))))
(defn mapx
[f coll]
(generate-iter
[f f, seq-cell (cell (sequence coll))]
(<< has-item seq-cell)
(f (<< item seq-cell))
(do (>> move! seq-cell) this)
(iter f (make-cell sentry (sequence @seq-cell)))))
(defn takex
[n coll]
(generate-iter iter
[ai (atom 0), n n, seq-cell (cell (sequence (coll)))]
(and (<< has-item seq-cell) (< @ai n))
(<< item seq-cell)
(do (swap! ai inc)
(>> move! seq-cell)
this)
(iter (atom @ai) n (make-cell sentry (sequence @seq-cell)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment