Hi, folks.

Just a quick newbie question.

One can create lazy sequences by wrapping each sequence element inside a 
'lazy-seq' macro while constructing the sequence. Usually it's done with 
recursion. But what if I need a tail recursive construction of the sequence 
(using recur) accumulating results by appending them to the end of an 
accumulator. It just works using 'conj' and vector until 'lazy-seq' is 
added to the picture. It then breaks append to the end vector semantics and 
the result is now reversed. Here is an example (just for illustration - no 
real world value):

(defn list-set
  "Returns a seq like s, except that the n-th element, using zero-based 
index, is x."
  [s n x]
  {:pre [(not (neg? n))]}
  (loop [s s, index 0, acc []]
    (if-let [s' (seq s)]
      (recur
       (next s')
       (inc index)
       (conj acc
             (if (= index n) x (first s'))))
      acc)))

(list-set [:a :b :c :d] 1 :zzz)
=> [:a :zzz :c :d]

Now with 'lazy-seq':

(defn list-set
  "Returns a seq like s, except that the n-th element, using zero-based 
index, is x."
  [s n x]
  {:pre [(not (neg? n))]}
  (loop [s s, index 0, acc []]
    (if-let [s' (seq s)]
      (recur
       (next s')
       (inc index)
       (lazy-seq (conj acc
                       (if (= index n) x (first s')))))
      acc)))

(list-set [:a :b :c :d] 1 :zzz)
=> (:d :c :zzz :a)

Is there a workaround or some idiomatic approach to this?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to