21 September 2021

# 'Threading' a Pedagogical Needle (part 1)

## IMHO, threading macros should be introduced started with `as->`.

One of the early mental hurdles that must be cleared when learning Clojure is the application of threading macros.

Usually the first macro we learn is either the thread-first (`->`) or thread-last (`->>`) macro. Sometime later, if you read the docs, you'll probably encounter the remaining threading macros:

The difficult thing about the thread-first and thread-last macros is that you have to mentally fill in the results being 'threaded' through the forms. Here's an interesting example from the thread-last docs:

``````;; An example of using the "thread-last" macro to get
;; the sum of the first 10 even squares.
(->> (range)
(map #(* % %))
(filter even?)
(take 10)
(reduce +))
``````

The difficult thing for the beginner is to imagine the result of each form being 'threaded':

``````(->> (range)
(map #(* % %) <result-of-range>)
(filter even? <result-of-map>)
(take 10 <result-of-filter>)
(reduce + <result-of-take>))
``````

If you simplify `<result-of-*>` (above) to something like `\$` you get this:

``````(->> (range)
(map #(* % %) \$)
(filter even? \$)
(take 10 \$)
(reduce + \$))
``````

...which is remarkably similar to the exact mechanics of `as->`:

``````(as-> (range) \$
(map #(* % %) \$)
(filter even? \$)
(take 10 \$)
(reduce + \$))
``````

Here's an example of how I used `as->` to prepare some hand-crafted html for a test assertion against the output from hiccup:

``````(let [tags (my-function-to-generate-tags)
lines
["<html>                                                       "
"  <body>                                                     "
"    <h1>                                                     "
"      Welcome!                                               "
"    </h1>                                                    "
"    <form action='/other/page' method='POST'>                "
"      <label for='foo'>Enter Foo:</label>                    "
"      <input id='foo' name='foo' type='number' value='3' />  "
"      <input type='submit' value='Foo' />                    "
"    </form>                                                  "
"  </body>                                                    "
"</html>                                                      "]]
(should= [:html ...] tags)
(as-> lines \$
(map string/trim \$)
(apply str \$)
(string/replace \$ "'" "\"")
(should= \$ (hiccup/html tags))))
``````

## Conclusion

The `as->` macro is much more flexible than `->` or `->>` and allows for easier visualization of what the macro is doing for you. Let's use it instead to introduce the concept of threading macros!

## Part 2

But wait, there's more! Head over to part 2.