Transcript from the "Challenge 3: Solution" Lesson
>> Kyle Simpson: Let's talk about the solution to exercise three. In the read me it says we need to define and compose that takes any number of functions and then a pipe. So basically you only need to solve this once and then do the reverse for the other one. Solve pipe first and do compose or the other way around.
[00:00:19] Let's try that out. Let's try to make our own. I'm gonna implement pipe first. And the way I'm gonna do it as that you expect to pass in individual functions, the way I've got listed on line line 11 and 12. So I'm gonna just collect all of those functions into a single array using the ...gather operator there in the function signature.
[00:00:42] And then what I'm gonna do is set up a variable to hold the input from the first function and then just keep reusing that variable over and over. So this needs to be a machine making machine. So I need to make a new function. That will receive the first input, which I'm just gonna call result.
>> Kyle Simpson: And then I'm gonna do this first with just a regular for loop. So I'll say for, and let's say i = 0; i < fns.length; i++.
>> Kyle Simpson: And now, what I wanna do is I want to call each function in succession so I wanna say fns[i]. I wanna call it passing in result and whatever that function returns store that in results so I can use it on the next loop iteration.
>> Kyle Simpson: At the end of this loop I just simple need to return the result. So this result here is the first input. We could have called it input. But I also think it looks weird to name this one input.
>> Kyle Simpson: And so, I would have preferred that one to be called result.
[00:02:16] And so, rather than have to do result equals input That's an entirely valid way of doing it, but there's really no reason to create two separate variables when one can work. So, my shortcut is to just call that first one result.
>> Kyle Simpson: Now, compose does exactly the same thing except it's gonna go in a different order.
[00:02:46] It's gonna take a list of functions And make a new function. Let me name this one, I'll name it piped and I'll name this one composed. It's gonna take a single result and I could start writing myself a foreloop for var i. And I would start at fns.length- 1 and I could go in the opposite direction with my for loop.
[00:03:10] But why don't I take a step back and say that's awfully imperative. Is there a more point free style way of thinking about this? And it turns out compose is really just the same as calling pipe, but with the reversed order of items in a list. All right.
[00:03:28] So what if I just say return pipe and the list of arguments that I give it, I need to spread those out. But I'm just gonna reverse the functions list.
>> Kyle Simpson: So that's a more point free style way of doing define and composing. You could have started with compose, and defined pipe as the reverse of compose, if that's the way you wanted to go about it.
>> Kyle Simpson: Now, as we scroll down here, we just are going to verify what's happening with compose, is that when we pass in the value 3 to f we're going to get three divided by two because we're calling the half function so that would be one and a half increment that to two and a half, double that to five decrement it down to four that's why we get the output of four.
[00:04:24] Or, I call P and I give it the value three. We're gonna decrement first. I'm sorry we're gonna halve first to 1.5. Increment to 2.5, double to 5, decrement to 4. So that's why F of 3 and P of 3 are gonna give the same it's cause' I listed these arguments already in the reverse order.
[00:04:56] Since we're going to cover recursion later in our workshop, I'm not going to devolve into much of the detail about recursion, but when you are running, for example, this pipe any time you have a loop, an imperative loop like that, that loop is taking the place of a constant.
[00:05:15] So the way you would model this is a recursion is to say, I just need to start out with a list of functions called the first function on the list and then pass that result to back in the pipe with a shorter list of functions and just keep going until your list of functions is down to one.
[00:05:37] It's the same thing as progressing through the list of functions, you can just reduce the list of functions. So that's the general strategy you'd use to do it with recursion. We're gonna talk about list operations later in the course as well. With a list operation, a function composition is basically a reduce.
[00:05:55] So we could have done it with a reduce.