Functional-Light JavaScript, v3

Piping vs Composition

Kyle Simpson

Kyle Simpson

You Don't Know JS
Functional-Light JavaScript, v3

Check out a free preview of the full Functional-Light JavaScript, v3 course

The "Piping vs Composition" Lesson is part of the full, Functional-Light JavaScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle discusses what piping is and how it differs from composition, which evaluates from the left to the right as opposed to right to left, and explains its usefulness.


Transcript from the "Piping vs Composition" Lesson

>> Kyle Simpson: One final time, let's go back to that candy factory. Because you, the engineer have really been working hard on this. And you have a big unveil to the boss and you say, I have finally cracked the problem. I realized that all the machines that we use to make candy all have a standard input and output valve.

And they all have standard ways that the wires plug, and the on off switches work. There's a nice standardization here. So what I realized is I could make a machine making machine. Drop in any three of those machines in whatever order you want. And out spits the nice boxed machine with the on off switch exactly the way we want.

Now I know it's stretching the metaphor, but hopefully you're seeing the connection to what we did with the composeThree utility. The composeThree utility is our higher order utility or higher order function, which is a machine making machine. It takes machines aka functions as inputs. Produces another function, another machine as an output.

That's what composition is all about.
>> Kyle Simpson: So we can take that same compose three utility and use it multiple times. If I call it with minus2, triple, and increment that's the F composition. Then it's going to first increment and then triple and then minus2. But if I give it those in reverse order, we end up with a different kind of function which produces a different result.

The same input 4 to F produces output 13. But the 4 input to p produces 7, why? Because the number 4 is incremented to 5, tripled to 15 and minus2 to 13 versus 4 minus2 is 2, tripled to 6, incremented to 7. So that math is not commutative and that's why we end up with a different result.

Two different as we said shipping rate functions, okay. But what if I wanted to define them in the opposite order? You could envision if we've envisioned to composeThree, you could envision a pipeThree, which we list them in the opposite order. Look at line 11 compared to line 5.

Line 11 has them listed in the same order as Line 5, but it produces a result that is the same as Line 6. It's the same as the p function. So in other words, pipe goes left to right, where compose goes right to left.
>> Student: Could you explain why if it's beyond the scope of this, that's fine.

But if you could just quick, why does that go off the back end in the pipe?
>> Kyle Simpson: So why does compose go right to left, and why does pipe go left to right, okay? I don't know the canonical, absolute correct the answer to that. But I can give you some anecdotal evidence for this.

If you think about something, imagine a function call where you say a parenthesis. I'll do it backwards here, a parentheses, b parentheses, c parentheses too. So you are listing them in ABC order, right? What order are they going to execute in?
>> Student: They should just go A, B, C.

>> Kyle Simpson: No, when you have A, parentheses, and then B, parentheses, and then C, parentheses, C executes first, and its output goes to B. Remember, back a couple of slides? That Compose utility, there's my fn3, fn2, fn1. Which one executes first?
>> Student: Well it's Compose so it's the f1.

>> Kyle Simpson: Well, don't worry about what Compose is, just look at line 3. Those three function calls, which one runs first?
>> Student: So we're going off of the DRS my aunt Sally stuff. So it'd be F1 cuz that's inside the inner parentheses first.
>> Kyle Simpson: Yes, that one has to execute first to produce a value that then gets past the FN2 which then produces a value that goes to fn2.

>> Student: So is it kinda, it's similar to the orders of operations in simple algebra? That you would do whatever's in the parentheses first?
>> Kyle Simpson: Yes, the simple way of saying it is, that's the way JavaScript syntax works, right? The way function calls work is that arguments are passed in a parenthesis set.

And the argument has to be computed before the function can be called. If the argument is itself a function, that function's got to be called with its arguments. If that argument is a function call that, so just by virtue of the way syntax works, you have to go sort of inner to outer.

It's not really right to left, it's inner to outer. But in this case, it happens to execute in a right to left function. So if you think about compose, if I had a code, literally that looked like line 3 somewhere in my app that said, fn3(fn2(fn1(some value. If that code existed in my app, and I wanted to refactor that code to use a composition.

I would write, compose and what order would I list the functions in the compose call? fn3, fn2, fn1, in other words, I would write the compose call in the same order as what is the equivalent of calls. And that's why it has to execute right to left to preserve the same semantic.

That's anecdotal explanation. I don't know if that's really why they define it that way. But in my mind they define it that way because it matches the source order.
>> Student: Good enough for me.
>> Kyle Simpson: Okay, let me jump back here. Pipe is an important operation because it has the left to right ordering.

And sometimes our brain is actually thinking, which one am I gonna do first? That's the thing on the left. I'm gonna do -2, and then I'm gonna do triple, and then I'm gonna do increment line 11. So sometimes it's more convenient for us to think left to right.

Oftentimes, it's more convenient for us to go right to left. Similar to what I said before where more people tend to, in my experience, more people tend to start off preferring partial application. And then eventually they become converts to the school of currying. The same thing seems to be true with piping and composing.

People that are not that familiar with all of the ins and outs of functional programming. Maybe they did dabble in it, but they don't do a lot of functional programming. They tend to like piping more, because they tend to think left to right, and right to left seems to be confusing and weird.

The more you do functional programming, the more you will realize you're going to use compose far more often than use pipe. So it's one of those things that is counterintuitive at first and then becomes more intuitive as you get more experienced with it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now