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