Reputation: 4432
How to understand this simple clojure code? I kind of understand what it is trying to do but can someone explain the syntax in great detail so I can confidently use it?
(map (fn [x] (.toUpperCase x)) (.split "Dasher Dancer Prancer" " "))
Upvotes: 0
Views: 238
Reputation: 20245
From Clojure REPL:
(doc map)
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments.
(.split "Dasher Dancer Prancer" " ") is generating a sequence of strings and each tokenized string will be passed to (fn [x] (.toUpperCase x))
However, (fn [x] (.toUpperCase x)) is too much unnecessary typing. You can do:
(map #(.toUpperCase %) (.split "Dasher Dancer Prancer" " "))
or:
(map (memfn toUpperCase) (.split "Dasher Dancer Prancer" " "))
Upvotes: 5
Reputation: 295403
This is defining a lambda (an anonymous function, which calls toUpperCase
on its single argument), and applying it (using map) to each result of String.split()
.
map
takes a function and a sequence of things to apply that function to, and returns a sequence of results from applying the function to the input sequence.
The following breaks the operation down into smaller pieces:
(defn upper-case-fn [^String x]
"this makes the same function, but not anonymous, and provides a type hint
(making it more efficient by avoiding the need for reflection)."
(.toUpperCase x))
;; you could also write the above like so:
(def upper-case-fn (fn [x] (.toUpperCase x)))
(def input-seq
"this assigns your input seq to a var; in the real world, with dynamic data,
you wouldn't do this"
(.split "Dasher Dancer Prancer" " "))
(def output-seq
"this is precisely the same as your sample, except that it's using a named
function rather than an anonymous one, and assigns the output to a var"
(map upper-case-fn input-seq))
;; if you enter this at a repl, you're looking at the contents of this var
output-seq
Upvotes: 4