Hi, Am 27.06.2009 um 02:23 schrieb _hrrld:
Am I doing something silly? Or perhaps I've misunderstood lazy-seq's operation.
I think, it's the latter. Here my try on an explanation: lazy-seq returns a value, which implements ISeq, ie. the seq interface. The code inside the lazy-seq is used to produce the actual seq. However it's execution is deferred. Only when you call first or rest/next on the lazy-seq, the code will be executed. So we get the first two rules: 1. lazy-seq should be outer-most. 2. The code inside a lazy-seq must return a concrete seq. For you example this means: (defn produce [pred generator value] (lazy-seq (when (pred value) (let [v (generator value)] (cons v (produce pred generator v)))))) What happens? lazy-seq returns a lazy seq %) which, when realised, return the cons of the generated value and another lazy-seq of the same type. As soon as the predicate returns falls, the block inside the lazy-seq returns nil and the sequence stops. Then there is a third important rule: 3. Don't hold onto the head. This is not applicable to your example, but it's good to know. And finally you can get something similar with Clojure sequence library. I think it's slightly different to your code, but maybe it also works for you. (defn slightly-different-produce [pred generator value] (take-while pred (iterate generator value))) Hope this helps. Sincerely Meikel
smime.p7s
Description: S/MIME cryptographic signature