Check out a free preview of the full The Hard Parts of Functional JavaScript course
The "Partial Application Example" Lesson is part of the full, The Hard Parts of Functional JavaScript course featured in this preview video. Here's what you'd learn in this lesson:
Will dives into an example of partial application, and demonstrates what happens in memory and in the execution context while the function is running.
Transcript from the "Partial Application Example" Lesson
[00:00:00]
>> Speaker 1: Here we go folk, it's known as partial application, this is our last code we see today. We're gonna create a function multiply takes an (a, b), returns a by b. We're hoping to convert it into a function multiplyBy2, so what we're gonna do is take into this prefillFunction function, the multiply function that takes in two inputs, and the thing we wanna prefill.
[00:00:26]
MultiplyBy2 is just multiply prefill where one argument is 2, right? It's just multiply with the 2 already prefilled. We're gonna take those two, throw them into prefillFunction, create our brand new function inner, which is actually what multipleBy2 is really gonna be. MultiplyBy2, it's all nice and nice pretty name but really, it's just gonna be inner.
[00:00:48]
And inner is gonna have a backpack full of our multiply function, there it is in fn and the prefilledValue. And I have a feeling when we run inner by its new global name multiplyBy2 it's gonna take in 5 and combine that with the prefilledValue from the backpack and run multiplyBy2 on it, and out it's gonna come.
[00:01:11]
We've gone and converted our and multiply by function multiply, see I say mulitplyBy2 many times. Multiply functions from arity of 2 to arity of 1, and it's gonna be a vital technique in practice. We saw that if we want our dream, and let's not lose sight of it people, that we want one thing and one thing only to be able to list off our lines of code, not as obscure hard to understand descriptive this computer is what you need to do, or undescriptive this computer what you need to do, and that, that line can affect anything else anywhere else on my app.
[00:01:51]
If I wanna have my dream where I can have each single line be nicely labeled and know that it's only consequence is in that line and then that's passed to the next line. And then the only consequence with that line is in that line, passed to the next line.
[00:02:03]
Then folk my goodness I'm willing to suffer a little bit to adjust my functions that have two inputs. When if I'm going to be listing off functions one by one each of them needs to take one input, return one output. Then that be the input of the next function, and it's only gonna take one input, and that's gonna return an output, I can just list off my lines of code.
[00:02:24]
I'm willing to suffer the process of adjusting my functions from taking two inputs to one. And we're about to see for our very last portion of code the process by which we can appear to edit our functions with arity of 2, inputs of two elements, into a function that only expects an input of 1 with no rewriting.
[00:02:51]
Now, to be clear, this is a simplified example declaring multipleBy2 doesn't seem to be that hard, but for many functions it's gonna be more complex. And also even here, this is a very nice way of declaring multiplyBy2. I'm explicitly determine I'm gonna use this previous code you recognize and then prefill its value.
[00:03:10]
All right, here we go people. Line one, the last section, here we go Seth. Seth, what are we doing in line one?
>> Seth: We'll be declaring a function named multiply.
>> Speaker 1: There it is into memory we go, and we declare a function named multiply. Uh-oh, what's it's a arity Seth?
[00:03:32]
>> Seth: 2.
>> Speaker 1: It's an arity of 2. Two inputs a and b return out a multiplied by b. There it is, thank you Seth.
>> Speaker 1: Virginia multiply's been saved, what's our next line Virginia? Notice by the way, for whatever reason I've declared this in the old style, we'll live with it.
[00:03:53]
What's our next lines gonna do, Virginia?.
>> Virginia: We're declaring a function called prefillFunction.
>> Speaker 1: PrefillFunction, there it is. I actually did leave that purposely. I knew it said the old style but I wanted you to remember nothing has changed. Sam, last or line here, left-hand side, we're declaring just what?
[00:04:16]
>> Sam: MultiplyBy2.
>> Speaker 1: Yeah, just a label, multiplyBy2. Okay, we already know, by the way, though it's gonna be the output of calling what, Sam?
>> Sam: PrefillFunction.
>> Speaker 1: Absolutely, which is gonna return out inner that don't look anything like multiplyBy2 to me. But that's because to create multiplyBy2 from multiply we're gonna have to do some really smart wrangling.
[00:04:39]
Mainly putting the multiply function and it's prefilledValue of the number 2 in the backpack of the inner function and get some memory, such that when we run multipleBy2, really inner, we're gonna behind the scenes be running fn whatever that multiply which will be in the backpack. All right, let's do it.
[00:04:57]
Let's do it. So we're gonna go and execute what Jasmine? What function are we gonna go and execute in order to get a result into multiplyBy2?
>> Jasmine: PrefillFunction.
>> Speaker 1: PrefillFunction, she's spot on. With the input of multiply, there it is, and the number 2. And its results is gonna me stored into what Jasmine?
[00:05:21]
>> Jasmine: It's gonna be stored into multiplyBy2.
>> Speaker 1: MultiplyBy2, she's spot on. We create a brand new?
>> Speaker 6: Execution context.
>> Speaker 1: Well done folk. And there it is. And it's really honestly just the kind of set up this execution context to get a function we can return out that has a backpack with our two important things in it that we can then use.
[00:05:44]
So, with that in mind, what is the first thing into the local memory that will end up in our backpack, Virginia?
>> Virginia: Function?
>> Speaker 1: Well, yeah, yeah-
>> Virginia: Multiply.
>> Speaker 1: Multiply, given what parameter name?
>> Speaker 1: What's the parameter name multiply's given?
>> Virginia: Fn.
>> Speaker 1: Fn, well done. No, no your spot on Virginia.
[00:06:05]
PrefilledValue then gets filled in with what, Virginia?
>> Virginia: 2.
>> Speaker 1: PrefilledValue is filled in with 2. I like to look of this people. It has all the stuff I need. There's multiply with its input of a and b and its output of a multiplied by b slightly condense.
[00:06:27]
And then the final thing, Andrew, same time as last time, what are we saving here? This is what we're actually gonna end up using, this is your path will be. Go ahead Andrew.
>> Andrew: We're saving the function inner.
>> Speaker 1: Inner. Andrew help me out this time, we're not just saving a function inner.
[00:06:41]
>> Andrew: We're saving the local-
>> Speaker 1: No, we're saving a link too?
>> Andrew: Yeah the link to the local memory.
>> Speaker 1: Exactly a link to the surrounding local memory, well done to Andrew. We get a link to,
>> Speaker 1: You get a link to,
>> Speaker 1: All the surrounding local memory, there it is.
[00:07:05]
And then, David, we're not gonna run inner, of course not, we wanna use it to pretend to masquerade as multiplyBy2. So what are we gonna do with inner?
>> David: We're returning it.
>> Speaker 1: We're returning it, well done. We return it out into what global label David?
>> David: MultiplyBy2.
[00:07:24]
>> Speaker 1: Into multiplyBy2, there it is. It was born as inner not anymore now we're masquerading it as multiplyBy2, what a con. I didn't know multiplyBy2 but in his backpack David is some really useful stuff. What is in that backpack that multiplyBy2 is gonna need?
>> David: The function multiply.
[00:07:50]
>> Speaker 1: Yeah under what label?
>> David: Fn.
>> Speaker 1: Fn. So multiply which takes in a and b and returns out a by b, and what else?
>> David: PrefilledValue.
>> Speaker 1: PrefilledValue. Which is what?
>> David: 2.
>> Speaker 1: 2. This [SOUND] combo here of function code and backpack is everything we need.
[00:08:15]
We've got the functionality when we run multiplyBy2, really inner. I have a feeling it's gonna run fn on or whatever we pass into inner and prefillValue, and then it's gonna be whatever we pass in by 2. That's it and we're gonna return that out. We're not really editing our function we're creating a brand new function that's got all the important stuff in its backpack.
[00:08:37]
And so this execution context everybody is what off the stack?
>> Speaker 6: On. Removed.
>> Speaker 1: Yeah, removed, popped off the stack. Let's actually put our cool stack up so we can keep track of it.
>> Speaker 1: We're in global again now and what do we go and declare next Babanesh?
[00:08:56]
>> Babanesh: The label [INAUDIBLE].
>> Speaker 1: The label?
>> Babanesh: Yeah.
>> Speaker 1: Label, which label?
>> Babanesh: The result label.
>> Speaker 1: Result label, there it is excellent from Babanesh. And we run, we run what looks like a really simple line. Low key behind the scenes it definitely isn't. Let's see multiplyBy2 input of 5.
[00:09:16]
We create a new, we're almost there everybody, a brand new?
>> Speaker 6: Execution [CROSSTALK]
>> Speaker 1: Execution context, multiplyBy2 is called with 5. Does multiplyBy2 just take in a number and multiply by 2? Uh-uh, uh-h [LAUGH]. No because we don't want have to create a brand new function multiplyBy2, we wanna be able to edit, the arity of our existing presave functions.
[00:09:38]
Now it may seem like there's a bit of a lot of work to do, but in the end, we don't build prefill function, is there for us in any functional language. Not in Java, so we have to be pre build this in JavaScript, but from now on that allows us to edit existing functions inputs, which we're gonna have to do quite a bit in practice.
[00:09:54]
Okay, mainly by the way, because things like if you use certain APIs that expect multiple inputs, we need to be able to adjust their inputs, not by actually editing the function, but by, cuz that's already gone, but instead by wrapping them up in the backpack of a new function that then pools that function with some of the inputs pre-inserted.
[00:10:13]
Okay, new execution context. And actually it's not the most sophisticated ever but it's not a small one either. I'm thinking it's just multiplyBy2 but of course it's not, here we go.
>> Speaker 1: There it is and it's an interesting one. What's the first thing, Michael, inside multiplyBy2? Well firstly everybody multiplyBy2 was born as what function name?
[00:10:40]
Everyone together.
>> Speaker 6: Inner.
>> Speaker 1: Well done. So Michael, when I run multiplyBy2 I'm really running inner, I'm not going back up, I literally return this code out, there it is. And what is the parameter?
>> Michael: The live input.
>> Speaker 1: Live input, he's spot on. I called it that because when multiplyBy2 is run that's the one we're actually gonna provide at that moment.
[00:11:02]
So the live rather than the one that's prefilled in the backpack for multiplyBy2. Okay, there it is. And next line Babanesh inside of multiplyBy2, inner,-
>> Babanesh: Output.
>> Speaker 1: Output. Yeah, declare output. And now its output will be the result of pooling fn with live input. These are our, you're gonna fill these in, aren't we in a second, prefilledValue.
[00:11:33]
Which is really saying, fn which is really, everybody together, it's not in local memory of multipliedBy2 it's in the backpack and it is what?
>> Speaker 6: Multiply.
>> Speaker 1: Multiply, well done folk. Multiply, and our live input, that's live right now and that is what everybody?
>> Speaker 6: 5.
>> Speaker 1: 5.
[00:11:54]
And our prefilledValue, we get that from the backpack as well and it is everyone?
>> Speaker 6: 2.
>> Speaker 1: 2! We look like we're running multiplyBy2 input of 5, nah, nah, nah we're running multiply with the input of 5 dynamically there and with the prefilledValue from the backpack of 2.
[00:12:09]
It's going to return out everybody?
>> Speaker 6: 10.
>> Speaker 1: 10, well done. And we store that into output. And then what do we do with that output folk?
>> Speaker 6: Return it-
>> Speaker 1: We return it out into results, and no one's any the wiser, multiplyBy2 with input of 5 returned out 10.
[00:12:30]
We're able to use that function now as an arity of 1 function anywhere in our listing of individual lines of code.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops