0

​​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" " "))

2
  • 3
    Could you be more specific about what you don't understand (and, similarly, what you do already understand)? Is it really just the syntax you need explained, or also, for instance, the Java interop primitives? The concept of lambdas? map? Be precise. Commented Aug 24, 2013 at 22:01
  • @CharlesDuffy I just need to understand the overall concept, how split followed my toUpperCase happening? Commented Aug 24, 2013 at 22:07

2 Answers 2

5

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" " "))
Sign up to request clarification or add additional context in comments.

1 Comment

It really is a good answer. Do I have to use the map if I use one method followed by another? Sorry I'm very new to clojure, that's why I have all these doubts. What do I have to do if I have to put another empty check in either of these two methods.
4

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

4 Comments

You are promoting to use type hints to avoid reflection. But this usually unnecessary unless it is proved that the algorithm will performs better by using type hints. Clojure is highly efficient and fast without providing type hints.
@Chiron I'm suggesting use of a type hint only in a specific case where it will in fact avoid an instance of reflection; if you used *warn-on-reflection*, it would back me up. Most places where it's overused are places where it isn't needed at all or won't do any good.
Good answer. Do I have to use the map if I use one method followed by another? Sorry I'm very new to clojure, that's why I have all these doubts. What do I have to do if I have to put another empty check in either of these two methods.
@javaguy You don't have to use map ever; it's just often the best tool for the job. If you wanted to do something else, you could write an equivalent for form, or a loop building a lazy seq, or... well, whatever you wanted. It'd probably be worth it to spend some time with a book that helps break down the concepts here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.