# francoisdevlin/Full-Disclojure

Fetching latest commit…
Cannot retrieve the latest commit at this time.

#Point Free Clojure

Last time we used the threading macros to reduce code size an abstract away list construction. In this episode I'd like to discuss a second style for combining code, point free. Point free code is a style that stresses partial application and functional composition. Let's start by reviewing these concepts in a simple fn.

``````episode-006=>(defn quadratic
[a b c x]
(+ (* a x x) (*  b x) c))
``````

Here we have a fn for evaluating any quadratic equation at any point x. However, sometimes we want to turn this general tool into a specific parabola. This is where partial application comes in. Let's use the equation x^2+x+1 as an example.

``````episode-006=>(def a-parabola (partial quadratic 1 1 1))

Note: Show examples
``````

Now, suppose we want add a coordinate transform to this. This happens all the time when you can't measure x directly, but you can measure some related value u instead. For our very simple example, we're going to use this transform

``````episode-006=>(defn left-shift [x] (+ 1 x))
``````

Mathematically, we want to do this

``````episode-006=>(a-parabola (left-shift 0))
``````

Notice that we have a chaining of fns calls here. The mathematical term for this is composition. Clojure provides a mechanism form doing this, the compose operator.

``````episode-006=>(def transformed-parabola (comp a-parabola left-shift))

Note: Show examples
``````

Now, for these examples I've broken up the partial application from the functional composition into different steps. However, I commonly will mix the partial application and composition together, yielding something like this.

``````episode-006=>(def transformed-parabola
(comp
(partial + 1)))
``````

You can also use point free style to rearrange code like you would with the thread-last macro. Let's revisit our square fn.

``````	Note:  Show square-free.
``````

Now, this form is a bit heavy and long to read. This leads some Clojurians to avoid point-free code. Others, from a Haskell background may wonder why Clojure doesn't have better reader support for composition and partial application. After all, Clojure claims to be a functional language, and as such these tools should be straightforward to code. One could experiment with extending the Clojure reader, but I have found a middle ground that I think works well. In my own libraries, I have the following two aliases sufficient:

``````episode-006=>(def & comp)
episode-006=>(def p partial)
``````

You'd be surprised how much easier a single character alias makes using a fn. For example, our square-free fn now looks like this:

``````Note:  Show other square-free.
``````

This is nicer than it was, but it is still a bit more work than the threading macro. However, we are only considering using our square-free fn on its own. The true value of point free style isn't apparent until you work in higher order fns. Suppose you wanted to map this squaring operation over a list of values

``````Note:  Show anon square free
``````

Notice how this fits into the mapping operation anonymously, and everything just works. This is the type of job where composition of fns "just works". map expects a closure, comp produces a closure. comp expects closures, partial produces closures. This is also very easy to grow organically.

``````Note:  Show working over a string.
``````

Suppose the input is a string, not a set of numbers. We just add the parsing steps, and it works. Suppose later we find out that we need to add a pre-filtering step to this data. Well, it's comp & partial to the rescue again.

``````Note:  Turn into nasty-huge expression
``````

You can also see that the indentation level of the form tells us something about the operation. I use this to quickly glance and determine what is going on in each stage of the overall process. I also use it a cue to figure out where one stage of the process ends, and another begins.

So, that's how I use point free style in Clojure. It's a different way to organize your code, and works well for certain problems. It's not good for everything, especially macro calls & forms with intended side effects. But, for purely functional applications it's handy. I hope this helps you think about problems from a different angle. And on that note, I'm Sean Devlin, and this is Full Disclojure.