Saturday, October 22, 2016

Clojure Plan, Map and Courage

This is one of those moments when the computer says NO!

Let's look at the interesting nature of Clojure's map function.

(defn foo[filenames]
    (map #(touchFile (str "/tmp/" %)) filenames))

Suppose we have a pre-existing function called touchFile that creates an empty file.

This foo function never created any files when called. I must have made a mistake with the directory path or perhaps my filesystem ran out of space or perhaps a bug somewhere in my touchFile function or perhaps...

Hang on, my test code for touchFile passes without any problem!

An attempt to prove something is wrong with the map call....

(defn foo[filenames]
    (map #(println (str "/tmp/" %)) filenames))

And nothing was printed out on my screen!

Something really sinister is going on here...

All you need is the plan, the road map, and the courage to press on to your destination.


After going back to the docs, it mentioned that "map returns a lazy sequence of...". Did you just hear the penny dropped?

So, the fix here is to invoke doall to force the map to evaluate each items immediately.

(defn foo[filenames]
    (doall (map #(touchFile (str "/tmp/" %)) filenames)))

Yay it worked!



Looking at a simple problem at 2 in the morning doesn't help a lot. It's probably time for me to hit the Zs.


No comments:

Post a Comment