Newbie here with a simple question: what is the preferred way of
mapping a function to a seq? Use an anonymous function or use a
partial?
Consider this:
user=> (map (fn [n] (+ 2 n)) [1 2 3 4 5])
(3 4 5 6 7)
user=> (map (partial + 2) [1 2 3 4 5])
(3 4 5 6 7)
user=>
I know that the answer is likely to be "it depends." I am just
interested in whether one is more idiomatic/functional than the other,
performance issues that one approach may have that the other one
doesn't, etc.
Thanks in advance,
PS: I'm even tempted to say that if one could do (map (+ 2) [1 2 3 4
5]) it would look even better :)
U
I did consider #(...) but didn't include it in the example as I tend
to prefer (fn [..] ...). For some reason my brain parses (fn...) much
better than #() (it looks more explicit).
If partial is a special case of #(..) could there be then a
performance penalty of using apply instead of a direct call?
My question stemmed from the fact that sometimes I find myself mapping
functions which are just partial applications of the same function and
perhaps having a bunch of partials lying around would make my code
read better.
Cheers for all the replies,
U
That's a very good point which I hadn't considered.
Perhaps the evaluation result could depend on the context?
E.g.
(def add-2 (partial + 2))
(def add-3 (add-2 1))
Then, hopefully:
(add-3 3) ; 6
(add-3); 3
U
The (partial...) style is called point-less, because you directly
manipulate the arrows and not the points.
It is the same kind of question as : should you use composition or
call (f (g x))?
Should I use the do-monad notation or a clever combination of m-bind,
map, and composition?
No good answer. Do what you like best in each situation.
If you want to have something looking like (+ 2) with multiple args
possible, I would advocate the best way might be to
add a reader macro to clojure expanding to partial. #p(+ 2) for example.
It is a better idea than using having evaluation depending of the context, IMHO.
Excellent.
> If you want to have something looking like (+ 2) with multiple args
> possible, I would advocate the best way might be to
> add a reader macro to clojure expanding to partial. #p(+ 2) for example.
> It is a better idea than using having evaluation depending of the context, IMHO.
I guess that this has just led me into learning yet another bit which
I wasn't even aware of! Thanks!
U
I meant, if you want to modify Clojure to allow a shorter notation for
partial application,
it is better to add a reader macro (directly in Clojure) than to
change evaluation semantic....
I am not sure it is a good idea anyway...
I brought this issue up in late 2008 and Rich decided against a reader
macro for that, as there already is the #() notation, which also has
advantages over partial, namely allowing you to call macros.
(map #(and true %) [1 2 3 nil 5]) ==> (1 2 3 nil 5)
but
(map (partial and true) [1 2 3 nil 5])
==> Can't take value of a macro: #'clojure.core/and
And this would also be the case for a currying reader macro.
Ah! What a nice caveat! (also applies to taking macros as arguments).
Thanks for your insights,
U