Subtitles section Play video Print subtitles (bright music) - [Shaun] So what is partial application? Well, in simple terms, partial application is when we take a function that has some number of arguments, and we fix some of those arguments to a set value. This function with fixed arguments can then be called from anywhere else in the code, and it'll be as if we had called the original function with all of its arguments. Another way to think about it as like this: Normally when we call a function, we have to pass all the arguments into it at the same exact time in place. What partial application allows us to do, is pass arguments to a function, at different places in the code, and then get the result, once the function gets all of the arguments it needs. Now, partial application is also a very useful way to configure more general functions into more specific ones. In general, if there's a function that we use often in our code, where one or more of the arguments that we call it with is almost always the same, this is usually a good candidate for using partial application. So now that we know what partial application is, what exactly does it look like in code? Well, let's imagine that we have a simple add function, that takes three integers as arguments, and adds them together. That would look something like this: We're going to say, try function, using this try function interface that we defined earlier in the course. And it's going to take three integers as arguments. So integer, integer, integer, and it's going to return an integer as well. We'll just call this function add. And what it's going to do is, it's going to take its three arguments, and add them all together, okay? So now that we have this function, what if we wanted to fix one of these arguments to a certain number, so that we only had to pass in the other two arguments later on? Well, what that would look like is this: We would create another function using the function interface, and this function will take a single integer as an argument, and it'll return a BiFunction that takes two integers as arguments, and returns an integer. And we have to import both the BiFunction and function interfaces up at the top. And for the name of this function, we're going to call it addPartial. And what this function is going to do, is it's going to take a single argument, and it's going to return another function that takes the other two arguments. And finally, once it has all of those three arguments, it's going to call add dot apply, with x, y, and z. So now that we have this addPartial function, calling it is going to look like this: We're going to say BiFunction, integer, integer, integer, and we'll say something like add five equals addPartial dot apply five. So now the first argument x has been fixed to five, by calling add partial dot apply five. And what we can do now is we can call this add five function with the other two remaining arguments. And I'm going to print this out, so you can see what it looks like. So we can say add five dot apply, and we can call it with the remaining two arguments, which are going to be y, and z here. And if we run this code, we'll see that it prints out the correct result. So this is five plus six plus seven, except we passed in the five and the six and seven in different places in our code. And that's what partial application is. So in this example that we just went through, we fixed the first argument x, and left the other two for later. But in reality, we can divide up our arguments however we want. For example, we could pass in the first two arguments, and leave the last one for later. And that would look something like this: We'd say function, and it would take two arguments and return a function, that takes an integer as an argument, and returns an integer. And what this would look like now, is it would take the first two arguments, x and y, and return a function that takes the last argument. And then it would call add dot apply, with those three arguments we'd accumulated. Oh, and this would actually be a BiFunction, instead of just a regular function. So now calling this is going to look a little bit different. We're going to say, function, since that's what this returns here, function, integer, integer, and we'll call this add five and six, equals addPartial dot apply, with y and z equal to five and six, okay? So what we're doing here is, we're setting x to five and y to six, so that we only have to pass in z later on, okay? So what we can do now, again, I'm going to print this out to the console, is we can call add five and six dot apply, with the final argument z, which we're going to say seven. And if we run this program again, we see that it prints out the same answer, except we're just passing our arguments in a different order now. And we also don't even have to pass in our arguments in the same order as we have here, right? We could pass in z and x here, and we could pass in the middle argument y later on, or we could say y and x and pass z later on, we could do it in pretty much whatever order we want. And obviously, in this case, that wouldn't make much of a difference, since the order doesn't matter of our arguments, but there are some cases where that would make a difference. So I'm just going to change these back to the way they were before. And one last thing that I want to talk about, is that we could even go a level deeper with our functions, and do something like this, where we have a function that takes the first argument, and returns a function that takes a second argument, and returns a function that takes the third argument, and finally, that returns the answer. Now, obviously, talking about these things can sound a little confusing sometimes. So what this is going to look like is, it's going to be a function, that takes an integer as an argument, and returns a function that takes an integer as an argument, that returns a function, and takes an integers and argument, and finally returns an integer, okay? Now that might look really confusing, and it kind of is, but this is just a fun example to go through. So bear with me. So what this would look like now, is we would define a function that takes an integer as an argument, and returns a function that takes an integers and argument, and returns an integer. And we could call this add five. And we'd say that that's equal to addPartial dot apply, and pass in the first argument five. And then we could say function, integer, integer, add five and six is equal to add five dot apply, and pass it in the second argument. And finally, we could say integer sum equals add five and six dot apply, and pass in the last remaining argument, which is seven. And if we print out the sum here, we see that that gives us the exact same answer, except obviously this is much more confusing. Now this specific case,