In my Clojure answer In the example for understanding , I have a function that processes its own output:
(defn stream [seed]
(defn helper [slow]
(concat (map
(declare delayed)
(let [slow (cons "" (lazy-seq delayed))]
(def delayed (helper slow))
delayed))
(take 25 (stream ["a" "b" "c"]))
("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac"
"aba" "abb" "abc" "aca" "acb" "acc" "baa" "bab" "bac" "bba")
It works by creating a direct link ( delayed), which is used as the second entry in a lazy sequence ( slow). This sequence is passed to a function that is lazy, and the output of this function (the very first part of the lazy sequence that does not need to be evaluated delayed) is then used to set the value delayed.
Thus, I will βtie the knotβ. But this is made much wider in Haskell (for example, the Explanation of "node binding" ). Given that Clojure has delayand force, I wondered, is there a better way to do this?
Question: can a (ugly, explicit) mutation ( delayed) somehow escape in the code above? Obviously (?) You still need a mutation, but can it be hidden by "lazy" constructs?
[I had a question last night with a similar name when I was still trying to figure out how to do this; no one answered before the code above worked, so I deleted it, but I'm not very happy with this approach, so I will try again.]
. : Clojure ref? ( , ).