Hi, Cecil. The difference is that doseq is used to produce side-effects, which is idiomatic, which is exactly what you did. When using doseq you can be sure that it's body will evaluate, whereas with map, for, reduce you can't - they expect pure functions, and produce lazy sequences, and there in no way for them to know that you want these sequences evaluated. At least, this is my understanding at the moment.
Because you said you liked clean code, I'd like to point out that your solution, although works, relies on mutating state of external vars, i.e. producing side effects, which is not necessary, and looks spaghetti-like, somewhat. Instead, you could modify return value of foo function to return a vector of [result, time], or, because you seem to not care about the result, time the function took to complete. It would look similar to what you already did: - first define a higher order function, that records executions time of a supplied function: (defn timed [f] (fn [& args] (let [start (.getTimeInMillis (now)) result (apply f args) end (.getTimeInMillis (now))] [result (- end start)]))) - define a timed version of foo: (defn foo' (timed foo)) - use it with doseq, because you are doing side-effects: (doseq [time (map second (map foo' numbers))] ;; alternatively, you can use threading macro: (doseq [time (->> numbers (map foo') (map second))] (println "it took" time "ms")) And it works! Without mutating global state, with pure functions - what a marvel. However, one piece is missing: number of threads the foo function was using - the whole point of this typing, eh, programming, I mean. You have 2 options here. First, the most obvious, is to return that number in foo. Second is applicable if you're doing what I think you're doing - applying the same computational algorithm using different number of threads. If second is true, you know number of threads you are going to use beforehand and foo could use them as input... ah, well, this is exactly what you were doing, I know realize, numbers being number of threads to use. Anyways, in light of this knowledge we can now rewrite doseq part as: (doseq [[time nthreads] (map (fn [n] [(second (foo' n)) n]) numbers)] (println nthreads "threads took" time "ms to compute things")) Yay! Note, that timed should work regardless of what function you supply to it. On Saturday, April 12, 2014 10:33:02 PM UTC+5:45, Cecil Westerhof wrote: > > 2014-04-12 18:19 GMT+02:00 Fergal Byrne <fergalby...@gmail.com<javascript:> > >: > >> >> On Sat, Apr 12, 2014 at 4:55 PM, Cecil Westerhof >> <cldwes...@gmail.com<javascript:> >> > wrote: >> >>> (->> numbers >>> (reduce timed-foo []) >>> (map format-time) >>> println) >>> >> >> (->> numbers >> (reduce timed-foo []) >> (map format-time) >> (map println)) >> > > That was my first thought also, but that displays nothing. > > But the following works: > (doseq [i (->> numbers > (reduce timed-foo []) > (map format-time))] > (println i)) > > -- > Cecil Westerhof > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.