Hero image

Function Composition


The last piece of the functional puzzle I am going through is function composition. It combines pure functions, first class functions and currying together into one thing. You can think of it as putting small pieces together to create a larger piece. Like a composer putting notes together to create music.

Really all function composition means is that you combine functions in order, taking the output of the first, and passing it to the second and so on until you run out of functions to call. The result is then passed back to the caller. If you are familiar with writing scripts in a terminal you may know this as piping output into another script.

Do we go down, down, left or right?

There are two ways of thinking about composing functions. The most common way you will see it is actually running backwards through the arguments. You can think of this as the maths way due to it being how mathematics symbolises functions - for example f, g => f(g(x)) - where g is actually run before f.

The opposite of this is the piped way, where you run the functions in the order you specify them. This looks like f, g => g(f(x)).

Both end up with the same result, and you will often see both options availabile with libraries for functional programming. Pick whichever you like more.

Basics

Lets look at some basic string manipulation you may want to do that is perfect for function composition. Strings in javascript are actually immutable, meaning they are a great way to learn about functional programming.

Lets say we have a persons full name, and we want to return it as only the first name with an uppercase first letter.

JS
Typescript

We could easily create another function to call these in order as we have done with getFirstNameCapitalised, but as we use composition more and more it would be create to have a tool to automatically do that part for us. We know our functions take one input and return one output so lets use this to our advantage. Lets assume our compose / pipe functions already exists and go straight to how it would be used.

JS
Typescript

Now all our getFirstNameCapitalised functions do the same thing. They each take a string name parameter, call getFirstName, and pass the result of that into the first parameter of capitaliseFirst. The output of that is then the final returned value.

Lets try and implement a simple version of this. We will only accept a single input parameter, and then call every function in our list until complete. There are more complex versions which accept more parameters, calls with no parameters etc. but we are trying to keep things simple for now.

JS
Typescript

Alright that looks a little tricky but following it step by step it is actually pretty simple. We use reduce here because it is an inbuilt function for javascript arrays that gives us the returned value of the last loop.

Note: To build compose rather than pipe, just use reduceRight instead, or reverse the functions array.

You can step through the code below to see it in action!


If you have never used it before - codeclip.io is an interactive tool where you can step through the code! Try using the step options below to see outputs.

NOTE - If you just see a blank square above you likely have 3rd party cookies disabled. You can see the same thing here.


A bit more complexity please!

So we have our simple pipe working, now time to get into the juicy stuff!

Did you realise that it now doesn’t matter how we group or nest composes! This means that we can separate out functions into meaningful blocks.

For instance - all the pipe functions below return the same result for the same input. One pipe is as good as another!

JS
Typescript

You can also split different pipes into variables if you find it helps documentation and supporting. The sayHiToCapitalised does exactly the same thing as the three examples above. All we have done is give more detail on what we are doing.

JS
Typescript

Conclusion

That is it for what I think is important when first learning about functional programming in Javascript. These are great ideas that you can include anywhere you write code. It doesn’t have to be separated into object oriented or not. Just use the tools available to you to write better code.



What to read more? Check out more posts below!