Hi,
Two problems I'd like to ask about.. (using clojure 1.0)
(1) The following code seems to work correctly
( generates Hamming numbers -- see
http://en.wikipedia.org/wiki/Haskell_(programming_language)#More_complex_examples
)
but...
;--------------------------------------------------------------------
(defn merge-seqs [xs ys]
(lazy-seq
(let [x (first xs) y (first ys)]
(cond (= x y) (cons x (merge-seqs (rest xs) (rest ys)))
(< x y) (cons x (merge-seqs (rest xs) ys))
:else (cons y (merge-seqs xs (rest ys)))))))
(def hamming
(lazy-seq
(cons 1 (merge-seqs (map #(* 2 %) hamming) (merge-seqs (map #(*
3 %) hamming) (map #(* 5 %) hamming))))))
(prn (nth hamming 5000))
;--------------------------------------------------------------------
...if I define merge-seqs using destructured binding of the function
arguments I get a java.lang.StackOverflowError.
;--------------------------------------------------------------------
(defn merge-seqs [[x & xs :as x-xs] [y & ys :as y-ys]]
(lazy-seq
(cond (= x y) (cons x (merge-seqs xs ys))
(< x y) (cons x (merge-seqs xs y-ys))
:else (cons y (merge-seqs x-xs ys)))))
;--------------------------------------------------------------------
Can that be avoided/fixed easily?
(2) Here's a simplified function in a similar vein but using
interleave for which the docs say "Returns a lazy seq" so I expected
it to work.. however this also gives me a
java.lang.StackOverflowError.
;--------------------------------------------------------------------
(def squares
(lazy-seq
(cons 1 (interleave (map #(* 2 %) squares) (map #(* 2 %)
squares)))))
(prn (take 50 squares))
;--------------------------------------------------------------------
If I replace the usage of interleave with the following hackish
interleave2 that uses lazy-seq directly, it works as expected...
;--------------------------------------------------------------------
(defn interleave2 [& colls]
(lazy-seq
(when (not-any? nil? (map seq colls))
(concat (map first colls) (apply interleave2 (map rest
colls))))))
(def squares
(lazy-seq
(cons 1 (interleave2 (map #(* 2 %) squares) (map #(* 2 %)
squares)))))
(prn (take 50 squares))
;--------------------------------------------------------------------
Is this a bug?
Is it because the call to apply in the original version breaks the
laziness of concat?
(defn interleave [& colls]
(apply concat (apply map list colls)))
I haven't looked if there are any other api functions that should be
lazy and fail in the same way?
Cheers,
Jon.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---