Iterate

typesince v1.10.63 clojure.lang/IterateEdit
satisfies ICollection IEmptyableCollection IMeta INext IPending IPrintWithWriter IReduce ISeq ISeqable ISequential IWithMeta

(Iterate. meta f prev-seed seed next)

Source code @ clojurescript:src/main/cljs/cljs/core.cljs
(deftype Iterate [meta f prev-seed ^:mutable seed ^:mutable next]
  Object
  (toString [coll]
    (pr-str* coll))

  IPending
  (-realized? [coll]
    (not (identical? seed UNREALIZED-SEED)))

  IWithMeta
  (-with-meta [coll new-meta]
    (if (identical? new-meta meta)
      coll
      (Iterate. new-meta f prev-seed seed next)))

  IMeta
  (-meta [coll] meta)

  ISeq
  (-first [coll]
    (when (identical? UNREALIZED-SEED seed)
      (set! seed (f prev-seed)))
    seed)
  (-rest [coll]
    (when (nil? next)
      (set! next (Iterate. nil f (-first coll) UNREALIZED-SEED nil)))
    next)

  INext
  (-next [coll]
    (-rest coll))

  ICollection
  (-conj [coll o] (cons o coll))

  IEmptyableCollection
  (-empty [coll] (.-EMPTY List))

  ISequential
  ISeqable
  (-seq [coll] coll)

  IReduce
  (-reduce [coll rf]
    (let [first (-first coll)
          v     (f first)]
      (loop [ret (rf first v) v v]
        (if (reduced? ret)
          @ret
          (let [v (f v)]
            (recur (rf ret v) v))))))
  (-reduce [coll rf start]
    (let [v (-first coll)]
      (loop [ret (rf start v) v v]
        (if (reduced? ret)
          @ret
          (let [v (f v)]
            (recur (rf ret v) v)))))))