> Thanks for the response everyone! I was able to get it working. If I > understand what everyone is saying, the following statement is true: > > In Clojure, laziness is the rule not the exception.
Rather than that, I'd say that you are thinking about map wrong (hope that doesn't come across as abrasive). "Map" in its purest sense says "take a collection of X, apply this function to each element of it to produce something of type Y and then give me the resulting collection". That is, "map" is more geared towards type "conversion" of the elements in a collection, but it is only converting the elements in the collection, not the collection itself. What you are looking for is something more like reduce. Reduce (also known as fold left) consumes a collection and turns it into something else. For example, you can implement doseq in terms of reduce as follows. (defn permutations "creates a sequence of all permutations of multiple sequences" [curr-seq & rest-seqs] (if (nil? rest-seqs) (map #(cons % '()) curr-seq) (reduce concat (map (fn [curr-seq-val] (map #(cons curr-seq-val %) (apply permutations rest-seqs))) curr-seq)))) user=> (permutations '(1 2) '(a b c d)) ((1 a) (1 b) (1 c) (1 d) (2 a) (2 b) (2 c) (2 d)) user=> (permutations '(1) '(a b) '(I II III)) ((1 a I) (1 a II) (1 a III) (1 b I) (1 b II) (1 b III)) (defmacro mydoseq "Uses reduce to implement doseq" [forms & body] (let [form-pairings (partition 2 forms) vars (vec (map #(first %) form-pairings)) assignments (map #(second %) form-pairings)] `(reduce (fn ~'[nothing args] (apply (fn ~vars ~...@body) ~'args)) nil (permutations ~...@assignments)))) user=> (doseq [a '(3 4 5 6)] (println (+ a 2))) 5 6 7 8 nil user=> (mydoseq [a '(3 4 5 6)] (println (+ a 2))) 5 6 7 8 nil user=> (doseq [a '(3 4 5) b '(5 4 3)] (println (+ a b))) 8 7 6 9 8 7 10 9 8 nil user=> (mydoseq [a '(3 4 5) b '(5 4 3)] (println (+ a b))) 8 7 6 9 8 7 10 9 8 nil user=> (macroexpand '(mydoseq [a '(3 4 5) b '(5 4 3)] (println (+ a b)))) (clojure.core/reduce (clojure.core/fn [nothing args] (clojure.core/apply (clojure.core/fn [a b] (println (+ a b))) args)) nil (user/permutations (quote (3 4 5)) (quote (5 4 3)))) Which becomes (reduce (fn [nothing args] (apply (fn [a b] (println (+ a b))) args)) nil (permutations '(3 4 5) '(5 4 3)))) Or, you can give a little bit different semantics: (defn combine "combines multiple sequences into a sequence of the collection of their nth elements" [& colls] (when (not (some nil? colls)) (lazy-cons (map #(first %) colls) (apply combine (map #(rest %) colls))))) user=> (combine '(1 2) '(a b c d)) ((1 a) (2 b)) user=> (combine '(1 2 3 4) '(a b c d)) ((1 a) (2 b) (3 c) (4 d)) user=> (combine '(1 2 3 4) '(a b)) ((1 a) (2 b)) (defmacro mydoseq2 "Uses reduce to implement doseq" [forms & body] (let [form-pairings (partition 2 forms) vars (vec (map #(first %) form-pairings)) assignments (map #(second %) form-pairings)] `(reduce (fn ~'[nothing args] (apply (fn ~vars ~...@body) ~'args)) nil (combine ~...@assignments)))) user=> (doseq [a '(3 4 5 6)] (println (+ a 2))) 5 6 7 8 nil user=> (mydoseq2 [a '(3 4 5 6)] (println (+ a 2))) 5 6 7 8 nil user=> (doseq [a '(3 4 5 6) b '(6 5 4 3)] (println (+ a b))) 9 8 7 6 10 9 8 7 11 10 9 8 12 11 10 9 nil user=> (mydoseq2 [a '(3 4 5 6) b '(6 5 4 3)] (println (+ a b))) 9 9 9 9 nil --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---