Learning Clojure: Thread-First macro

Clojure is a fun programming language with a ton of hidden features. At the surface, it seems like you might be lost in parenthesis hell and find yourself struggling to read code. Have you ever written code like this?

Where do you even start? Obviously this is a terribly trivial example on how to add a number to a sequence three times. Yes, there are much more efficient ways to do this, but this is just an example. What if there was an easier way to write AND read this? There is…and it’s called the thread-first macro.

-> Macro (Thread First)

Threading? Do I need to bust out my computer science books? This actually has *nothing* to do with threading in the common sense with spawning threads for memory and efficiency purposes. When we say “threading” here, we are talking about threading the result of one thing into the first argument of another function. The threading macro passes its first argument as the first argument to the next statement, then passes the result of that expression as the first argument to the next statement and so on. Here is an example on how this would look for our trivial example above:

This is MUCH easier to read than the above form and can be interpreted as, “Given a sequence [123], add 4 to it, then take the result of that sequence [1234] and add 5 to it. Then take the result of that sequence [12345] and add 6 to it”

But doesn’t conj take two arguments? I don’t get how this works.

The thread-first macro literally inserts itself as the FIRST argument of a function for each line that is added. conj is defined as (conj item). In the above example, the sequence is purposely omitted because the threading macro automatically inserts it.

That’s confusing, is there any way to make it easier?

One of the tricks I learned was to use an ignored character in Clojure, such as a comma, and insert it in place of the second item in the function. So the above code can be modified to look like this:

Once you get used to it, refrain from using the comma in your code; but it should help you to get started.