What is function composition?
Articles Blog

What is function composition?

October 9, 2019

What is function composition? By the end of this episode, you will know
what function composition is and why it’s useful. My name is Eric Normand, and I help people
thrive with functional programming. This is an important topic because it’s something
we do all the time. We do function composition in both functional
and non-functional styles of programming. Functional programmers and mathematicians
have named it, they’ve named it functional composition, and they’ve turned it into a
higher order function. It’s something that we tend to talk about
probably more than you would in a non-functional language. What is it? It’s pretty simple. It’s when you take a function and you call
it, and then you take the return value of that function and you pass it to a second
function as an argument. You’re chaining the function calls. Usually, in math or as examples, we use function
f and g. You call function g, you get the result. You take that result and you pass it to function
f. Of course, you get the result of function
f. There’s a special case because sometimes you’ll
need some other arguments, like f will take it as the second argument. It will take the result of g as the second
argument. There’s a special case where you take that
return value of g and you pass it as the first and only argument to f. That’s a special case because it’s very simple
and easy to reproduce in your code that you can just do f, open paren…I’m using JavaScript
syntax, f, open paren, g, open paren. You put the arguments to g, and then you close
the paren and you close the paren of f. Now, the g is the…You don’t even need to
name that return value, you don’t need to save it into a variable. You pass it directly to f. If you take this special case — because it’s
so regular — you can turn it into a higher-order function. That is, a function that takes f and g and
returns a new function that does that same thing, that does the f open paren g. Mathematicians usually use the dot as the
operator for a function composition when they want to talk about it in a paper or something. They’ll write, “f.g,” to mean f composed with
g. This gets confusing, and it’s one of the reasons
why function composition is thought of as difficult. The confusing part is that the g is called
before f, even though it comes to the right of f. If I do f.g, the g is called first, and then
the f is called on the result of g. It looks backwards. It looks like, “Call f,” and then, “Call g,”
but the g is called first. That makes it confusing. The reason it is that way is, like I said,
it’s like doing f open paren g, open paren, put the args of g, and then close the parens. They’re in the same order as if you were to
call it directly, but for clarity, you might want to move the g out of there, because it’s
inside out. The arguments get evaluated first before the
function gets called on those arguments. If you move the g above there, and you called
it g result equals g, and then you called it with its arguments, and then after that,
you did f open paren g result… I’m trying to talk through code, but the idea
is that it’s in the same order as something you should be familiar with. It’s just when you look at it on it’s own
and that’s not explained to you, it looks backwards. Why do we talk about this? Why do we want to turn this into a higher-order
function? First of all, it’s very common to do this. It’s common to call a function and pass that
argument to the next one. Even though it’s less common than the general
case, the special case of the single argument is still really common. Let’s say you wanted to double a number and
then square it. You could double it, so you call the double
function, then you take the result of that and you pass it to the square function, which
then returns the value. You could say, “This is a function composition,”
and you can call compose with the two functions. That gives you a new function, which is the
double square. What it does is it reduces boilerplate. By reifying it…I have a whole episode on
reification if you want to know what that is. I also have a whole episode planned for higher-order
functions, if you want to know more about that. You’re taking this idea that normally you’re
just doing code by embedding the call to g as an argument to f. You’re now turning it into an object, a function,
called compose, that can do that. Now, this thing can be manipulated like any
other function, like any other value. This compose function is not just a bit of
syntax that your language understands. It’s a function that your code can understand,
that your program can use. Then you can pass it to other higher-order
functions like map, and other stuff. You’re getting leverage by turning it into
a first-class thing. I do want to say that it’s not always clearer
to do this, to use compose. It’s something that people do use, though,
and so, if you’re doing functional programming, you should probably understand it. It’s something that you’ll see a lot. One place where it really is used a lot is
in a thing called point-free style. I have a whole episode planned on point-free
style. Basically, point-free style is very simple,
is a way of defining functions without naming the arguments. I could write a function. I call it fg, or f.g, that’s the name of the
function. It takes arguments, those arguments get passed
to g, and then g will return a value. That return value will get passed to f, and
that return value f will get returned from f.g. I can write that function, and I can write
it over and over again for different fs and gs. I could write it for square and double, and
I can write it for trim and capitalize on strings. There’s all sorts of examples that I could
write by hand each time, or I could call compose, and not have to name the arguments, not have
to repeat that boilerplate. This point-free style is a way of building
functions without naming arguments. To be very frank, arguments take up a lot
of brain space, if you have to name the argument, you have to think of a good name, otherwise,
it’s going to be worse than not having one, and they take up code space. You don’t want to be naming them if you don’t
have to if it’s not going to add to the clarity. There’s this thing called point-free style. Function composition is used a lot in it because
you don’t have to name the arguments. Another cool thing about function composition
is that it is associative and it has an identity. There’s a whole episode on what an identity
is. Notice if I do f composed with the identity
function… The identity function is just a function that
returns its argument. You pass in the number five, it returns the
number five. You pass in the string “Hello,” it returns
the string “Hello.” It doesn’t do anything to it. You think, “What’s the point of this function
that doesn’t do anything to it?” It’s just like, “What’s the point of zero?” It represents nothing. Representing nothing is actually very useful,
and so is representing a function that does nothing. [laughs] It’s now able to be the identity value of
function composition, so f composed with identity is the same as f. Identity composed with f is the same as f. The identity function is the identity value
of function composition. You might want to write that down because
it’s a mouthful. It’s associative, which I have a whole episode
on that. Real quick, it means the grouping doesn’t
matter. Imagine I have f composed with g, composed
with h. I can put the parentheses around the f and
the g, or I can put the parentheses around the g and the h. I get the same thing. I get the same result. The function at the end of the day that I
get from that whole big expression is going to do the same thing. When you have something that’s associative,
and it has an identity, that means it is a monoid. I have an episode planned on monoids and what
makes them cool. That’s just a cool thing I wanted to mention
at the end. If you don’t understand it, just wait for
that episode and it will come. This is the kind of thing that happens when
you start dealing with functions as first-class objects, especially higher-order functions. You can start to get these kinds of cool algebraic
properties that come out. I just know when I’ve talked about this in
the past, the really common question is, “Why do I need this? Why do you need it?” The truth is you don’t need it. You can do manual function composition each
time. You can, but then the other question is, “Why
do you need anything?” You can always just do for-loops and gotos
if you want if your language has gotos these days. Why do you use map instead of for-loop? Basically, if you can use a map, map is way
less error-prone than a for-loop. You don’t have to initialize any variables. You don’t have to get the end condition right. If you can use a map, it’s probably less code
than a for-loop. That’s not really what matters. What matters is that it’s less error-prone. The cool thing is that once you have map,
map is a function. Map is something that can now participate
in all these other higher-order functions. Same with compose. You could do it manually, but then you don’t
have a function called compose that you can use in other ways. This is part of, I would call it, the leverage
of functional programming. Just by turning this thing that you do a lot
into a function that can now participate in the rest of the ecosystem, you now have this
leverage. For now, you’re acting in this higher level. Now, you’re composing compose. You’re mapping compose over things, which
you couldn’t do before. You could do it, but you’d have to write out
compose each time you wanted to. Let me recap. Function composition is simply when you take
the return value of one function and pass it as the argument to the next function. You can imagine making a function that just
does that. You’ll realize that you do that over and over,
that there’s a common pattern. You could just make a function that takes
the two functions and returns that common pattern function. That one is called function composition. It’s the special case. Mathematicians use a dot. Even in Haskell, probably other languages,
they use a full stop or the period character to indicate function composition, just because
it looks like a dot. Because it’s so easy to do, it’s just a dot,
you do it a lot. It reduces boilerplate and then it reifies
this concept into something that now you can leverage in with the rest of your functions. It’s used a lot in point-free style and it’s
a monoid. It has an identity and it is associative. At the end, I’d like to give you, I think
of it like homework or something that would help you use this knowledge that I’ve just
talked about. I think that it would be a good learning experience
to write your own implementation of function composition. It’s not hard. Like I said, it’s just f, open paren g in
JavaScript. You need to write a function called compose,
let’s say, that takes two functions as arguments, does the composition and returns the return
value of them. It returns a new function that does the composition
of the two. You can look it up if you have to. If your language has first-class functions,
it is really like a three-line function. It is nothing big. You don’t have to do the full-blown, industrial-strength
one that can handle multiple arguments and things like that. Just a function of one argument, composed
with another function of one argument. Just try that out. That will really help you understand what
it’s doing and why they’re in the order they are. That was a favor for you. Go ahead, do that for yourself. Learn a little bit deeper than what you can
in a podcast. I’m going to ask a favor for myself. If you liked this episode, please share it
with your friends and please subscribe. If you share it with your friends, then it’s
just another thing to talk about with them. You probably have coworkers who would like
to know a little bit more about this functional programming stuff. If you subscribe, then you will get the next
episode, which also has good stuff that you’ll probably like if you liked this one, because
that’s how it is. I will have more stuff coming. Thank you very much, and see you next time.

Leave a Reply

Your email address will not be published. Required fields are marked *