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 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