23 August 2021

# Clojure Maps as Functions

## Just a little Monday morning 'ah-hah!'

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!