Hi Nathan,

On 31 Mrz., 09:40, Nathan Sorenson <n...@sfu.ca> wrote:
> First of all, I would like to thank Rich and this community for
> producing such a pleasurable language, and for putting up with with
> all the unpleasant nit-picking of new users. That being said...
>
> I am curious as to why the function parameter is specified before the
> collection parameter in map/reduce. I have never used a lisp before,
> and may not be aware of idiomatic style, but it seems to be the
> convention elsewhere in Clojure (assoc, conj, .method calls, etc...)
> to have the "altered" data structure be the first parameter.

I believe this is to allow more than one sequence in map expressions:
(map - '(1 2 3) '(3 2 1)) => (-2 0 2)
and for reduce, it takes another optional arg to start the reduce
with:
(reduce conj [1 2] '(a b)) => [1 2 a b]

> Would this not allow mixing map into a threaded expression:
>
> (-> [1 2 3]
>  (map inc)
>  (assoc 0 4)
>  (reduce +)
>  (conj :anotherthing))
>
> Perhaps this style is rare in practice? Certainly it is easy enough to
> write a custom map/reduce which acts this way, so I suppose my
> question is mostly philosophical.

there was a thread devoted to a macro to express this kind of piping,
http://groups.google.com/group/clojure/browse_thread/thread/66ff0b89229be894/e78c3585589cdbf6?lnk=gst&q=pipe#e78c3585589cdbf6

(defmacro pipe
  "Threads the expr through the forms. Inserts x as the
  last item in the first form, making a list of it if it is not a
  list already. If there are more forms, inserts the first form as the
  last item in second form, etc."
  ([x form] (if (seq? form)
              `(~(first form) ~@(rest form) ~x)
              (list form x)))
  ([x form & more] `(pipe (pipe ~x ~form) ~...@more)))

which is the same as the -> except it threads its first arg to the
last position of each form instead of the second
(pipe x (f a b)) => (f a b x)

Using this macro is IMO good for expressing long chains of filtering,
mapping and reducing, its more readable, less nested and easier to
edit than the equivalent nested expression. I have some code which is
using this macro, but most of the time I just don't need such long
pipes or I'm using a let to create named intermediate results for
debugging and sanity.

In the above mentioned thread, there is also a more general let->
macro which would make your example work without any modifications to
the core functions:

(let-> x [1 2 3]
  (map inc x)
  (into [] x)
  (assoc x 0 4)
  (reduce + x)
  (list x)
  (conj x :anotherthing))
=> (:anotherthing 11)


erik

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

Reply via email to