As stated in "Learn Clojure - Hashed Collections":
There are several ways to look up a value in a map...When the map in question is being treated as a constant lookup table, its common to invoke the map itself, treating it as a function...
I've known this for a while, but an implication of this property surfaced for me today. Suppose we have a map:
(def characters
{nil " "
:O "O"
:X "X"})
The purpose of this map is to allow us to represent a tic-tac-toe grid as a string. Internally, we are using nil
, :X
, and :O
to represent board state and need to 'map' those values to corresponding strings. Here's how I started:
(def characters
{nil " "
:O "O"
:X "X"})
(->> grid ; [:X nil :O :X :X nil :O :O nil]
(map #(get characters %)) ; ["X" " " "O" "X" "X" " " "O" "O" " "]
(apply str)) ; "X OXX OO "
Summary: Start with a grid, map each value in the grid to its corresponding character using an anonymouse function that calls
(get characters %)
and combine them into a single string.
Then it hit me: the map itself is the function!
(->> grid
(map characters)
(apply str))
So, start with a grid, map it over the characters (using the map as the lookup function!), and combine the result into a single string. No need to define an anonymous function!
Since this was the only usage of the defined characters
map I decided it could be inlined:
(->> grid
(map {nil " ", :O "O" :X "X"})
(apply str))
Start w/ the grid, map
nil
to a space,:O
to the"O"
character,:X
to the"X"
character and make a single string.
Voila! I'm probably just scratching the surface with this realization. It's these kind of straight-forward approaches that make programming in Clojure such a joy!