I'm passing the name of a function for use in another method.
(defn mapper [m function]
(cond
(= '() m) '()
true (cons (function (first m))
(mapper (rest m) function))))
(println (mapper '((blue red)(green red)(white red)) #'first))
Is there a more idiomatic way to do this in clojure?
#'first
is the var called "first"; first
is the value of the var called "first", i.e. the fn. In this case (#'first foo)
and (first foo)
give the same answer, but #'first
does an extra dereference every time you call it. So don't do this unless you want that dereference to happen over and over. There's usually no need to use #'
.map
is lazy, whereas yours isn't. The built-in map
takes advantage of chunked seqs for better performance, whereas yours doesn't. Idiomatic code doesn't have to be lazy or use chunked seqs, but keep in mind that the builtins have some of this magic going on. So it's good to take advantage.(= '() x)
, the idiomatic test for an empty seq is (seq x)
, which returns nil
if x
is empty. Note that in Clojure, (= '() nil)
is false.()
.map
takes the function argument first because it accepts multiple collection arguments. When a function takes multiple arguments, those arguments have to go last in the argument list. I think it reads better the other way too: "(map f coll): map this function across this collection".cond
if you only have two options. You can use if
instead. And if one of the branches in your if
returns nil
, you can use when
. It's nice to use when
and if
when appropriate, because they signal your intentions to the reader immediately, whereas cond
could do anything and forces the reader to read more.Rafał Dowgird's version is idiomatic, except I'd flip the order of arguments around. And I'd call it like this:
user> (mapper first [[:blue :red] [:green :red] [:white :red]])
(:blue :green :white)
I believe you got it mostly idiomatic. Clojure's own map
uses:
(defn mapper [coll f]
(when-let [s (seq coll)]
(cons (f (first s)) (mapper (rest s) f))))
I have shortened it severely - the original produces a lazy sequence, deals with multiple collections, chunked-seqs, etc. By the way - I assume you want to pass the actual function, not it's name.
The coll
and f
are idiomatic arg names to represent collections and functions, respectively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With