One nitpick I noticed, reduce is eager, not lazy.

On Tue, Apr 15, 2014 at 9:25 AM, Alex Vzorov <alex.vzo...@gmail.com> wrote:

> 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>:
>>
>>
>>> On Sat, Apr 12, 2014 at 4:55 PM, Cecil Westerhof <cldwes...@gmail.com>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.
>

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

Reply via email to