Если вам требуется изменяемое состояние, используйте один из типов ссылок clojure:
user=> (defn reader-for [coll]
(let [a (atom coll)]
(fn []
(let [x (first @a)]
(swap! a next)
x))))
#'user/reader-for
user=> (def f (reader-for [1 2 3]))
#'user/f
user=> (f)
1
user=> (f)
2
user=> (f)
3
user=> (f)
nil
Кроме того, let
для лексического обзора, binding
для динамического определения.
Редактировать: поточно-ориентированная версия, указанная Аланом.
(defn reader-for [coll]
(let [r (ref coll)]
#(dosync
(let [x (first @r)]
(alter r next)
x))))
И просто для забавы, потокобезопасная версия с атомами (не делайте этого):
(defn reader-for [coll]
(let [a (atom coll)]
(fn []
(let [ret (atom nil)]
(swap! a (fn [[x & xs]]
(compare-and-set! ret nil x)
xs))
@ret))))