Dealing with data
When writing functions in Clojure, the first step is extracting the data you need in order to do the required computation.
Here are two techniques that are helpful.
The let
form
The let
form can be used to define new variables. This is extremely useful because it allows you to assign meaningful names to values used in the computation.
The let
form is
(let [var1 val1 var2 val2 …] body)
Each value (val1, val2, etc.) is evaluated in order, and the results are assigned to the variables var1, var2, etc. The result computed by the let
form is the result of evaluating the body expression, which can refer to the variables.
For example, let’s say that we want to write a function to compute the geometric distance between two points, where each point is represented by a two-element vector. E.g.:
Here’s one possible implementation:
This is pretty ugly because there is a lot of redundancy. Here’s a better version using the let
form:
In addition to eliminating the redundancy, the variables make the code more readable by giving meaningful names to values used in the computation.
Destructuring
Destructuring allows you to automatically extract data from a sequence or map argument.
For example, the geom-dist
function defined earlier accesses elements of two parameter vectors using the built-in first
and second
functions. However, since both of the parameter vectors are expected to have exactly two members, we can destructure them into their members directly:
This is even simpler than the previous version, and arguably more readable as well.
The let
form also supports destructuring:
This isn’t quite as concise as the version above where the parameters are destructured directly, but it’s still an improvement over making explicit calls to the first
and second
functions.
It is also possible to destructure maps. For example: