Question

The say-hello-to-first-person works fine, why doesn't say-hello-to-everyone?

(defpartial greeting [name]
  [:p.alert "Hello " name ", how are you?"])

(defn say-hello [name]
  (append $content (greeting name)))

(defn say-hello-to-first-person [names]
  (say-hello (first names)))

(defn say-hello-to-everyone [names]
  (map say-hello names))

(say-hello-to-first-person ["Chris" "Tom" "Jim" "Rocky"])
(say-hello-to-everyone ["Chris" "Tom" "Jim" "Rocky"])
Was it helpful?

Solution

You want doseq, Clojure's "foreach":

(doseq [name names]
  (say-hello name))

map doesn't work because it produces a lazy sequence: Until you actually access the items in the sequence (which you don't here), none of them will be evaluated, and side effects won't occur.

Another option is to force evaluation by wrapping dorun around the map. Thinking about why this works may help your understanding (although doseq is the idiomatic approach here).

OTHER TIPS

As @edbond says in his comment, map fn don't evaluate until necessary moment because map fn returns a lazy seq.

This is the doc of map fn 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.

If you need to be sure that the values are evaluate in one specific part of your code you can use doall or dorun

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top