Check out a free preview of the full The Hard Parts of Functional JavaScript course

The "Generalizing Functions" 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 demonstrates how to use a generalized function and how to pass, as a parameter, specific instructions in the form of another function.


Transcript from the "Generalizing Functions" Lesson

>> Will Sentance: We just saw, we had three incredibly boring, repetitive functions, each time exactly the same besides one little change. And so now we realized there must be a better way. Eric was bored. It was rude of him to say so. No, Eric was bored. It was very nice of him to acknowledge that and he should be.

Cuz we need a better way. We do know where to build our individual functions every time we wanna take an array, create a new array, take each element of the input array and do something different to it. What if there are ways instead of leaving a placeholder, a blank, into which we would then when we run that function, specify exactly what we're gonna to each element of the array.

The first time we run the body of that for loop there, i is gonna be 0, array position 0 is gonna be number 1, instructions will be multiplied by 2, multiply by 2 input of 1, insert the 1, return out the 2, push it to output. And then again and again.

People, let's see it in action. Here we go folks, starting with Jasmine. Jasmine, what do we do, my friend, here in line one of our code, what are we saving first here?
>> Jasmine: We're declaring copyArrayAndManipulate.
>> Will Sentance: CopyArrayAndManipulate, so we're gonna leave blank exactly what it's going to do to each element of our array.

So we save that function there in our memory, so thank you to Jasmine next slide, Virginia, little baby function here. What's it gonna do?
>> Virginia: So we're going to create a label, multiply by 2.
>> Will Sentance: Yeah, and it's what?
>> Virginia: And we're gonna go off, and-
>> Will Sentance: Assign a?

>> Virginia: Assign a function.
>> Will Sentance: Assign a function, she's the bomb, exactly. Next line, Sam left hand side first.
>> Sam: Declare a constant result.
>> Will Sentance: Excellent, and we then need to go and do some work, right, Sam? Which is to go and invoke, go and run what function?
>> Sam: CopyArrayAndManipulate.

>> Will Sentance: CopyArrayAndManipulate input of 1, 2 and 3 and folk, the entire functionality of multiply by 2, there it is. And we're gonna create, in order to run the CopyArrayAndManipulate code, we're going to create a brand new. [LAUGH]
>> Will Sentance: Yeah, thank you, Bivanesh, [LAUGH] nothing makes it better than when some person decides to say local and that's completely correct and everyone else says it.

Perfect Bivanesh, exactly, a local execution context, but let's call it an execution context, a brand new execution context with its own little local memory. Into it we go, and the easy bit first. Andrew, array is going to be filled in with?
>> Andrew: 1, 2, 3.
>> Will Sentance: Exactly, our parameter array will be assigned the value, which is our argument 1, 2, 3.

And then the hard bit, David, our parameter, our placeholder instructions is gonna be filled in with what David?
>> David: Result of multiplying by 2.
>> Will Sentance: Not the result. That's a label for the functionality, Sam?
>> Sam: It's the reference.
>> Will Sentance: Yes, and that it is a link back but let's just say for now it is the?

>> Group: Function.
>> Will Sentance: The function definition of?
>> Group: Multiply by 2.
>> Will Sentance: Multiply by 2, meaning wherever you see instructions inside of it, and don't, David, absolutely understandable to make that confusion. Wherever you see instructions inside of here, know that it is being filled in with the code of multiply by 2, meaning you're literally going to throw away the word instructions and multiply by 2 is going to go in there.

Just like, not everyone knows, this just like wherever you see array inside that function that's literally going to be thrown away and replaced with 1, 2, 3. We could literally throw away ran at the 1, 2, 3. So it's a 123.length, 123[i], everything becomes a value in JavaScript.

Nothing just becomes like a kind of it might be this. It's a value. It's a thing. Including instructions, which becomes exactly meaning there it is, multiply by 2. Meaning Virginia, it's still strange, it's my sister name. Meaning if, Virginia, I want to run multiply by 2 inside this function.

I don't use the label multiple by 2, what they will do I use Virginia?
>> Virginia: What label?
>> Will Sentance: What label do I use, Eric, to run the?
>> Eric: Instructions.
>> Will Sentance: Instructions, so if I wanted to run multiply by 2, what specifically would I write, Mike? Michael, what would I specifically write if I wanted to run multiply by 2 inside of this function?

>> Michael: Instructions.
>> Will Sentance: Instructions and, if I want to run it.
>> Michael: Parentheses.
>> Will Sentance: And parentheses, and I guess given its multiplying a number by 2 and is expecting an input I'd put something in there. That is really running multiply by 2, multiply by 2 input of 3, okay?

Instructions is our general name, meaning I could run copyArrayAndManipulate on any function. I would have it take in divide by 2 and instructions would be filled in with divide by 2. This is getting very general. Very very nice. That makes us very happy. All right, excellent, now we're trying to produce a new array.

So Anna, what's the first thing we do inside a copyArrayAndManipulate after we've handled our inputs, we produce a? We declare a?
>> Anna: Output.
>> Will Sentance: Output and it is a?
>> Anna: Empty array.
>> Will Sentance: Empty array, exactly, there it is, empty array. And let's get iterating. You know what? I'm gonna do my cool stack just this time just because we're recording this for posterity I want to be able to keep track of this, we're always in global.

What are we in now, Bivanesh? What function are we calling right now?
>> Bivanesh: The copyArrayAndManipulate.
>> Will Sentance: Excellent, copyArrayAndManipulate, Bivanesh, I remembered your name right, right?
>> Bivanesh: Yeah.
>> Will Sentance: Yeah, all right there it is. 1, 2, 3 is our array, and then we've got our output we're going to work with and put stuff into.

Now things get interesting. Body of the for loop between the curly braces, inwards, outwards, JavaScript never works on something where it needs something else to figure out what it is. So, it always takes the thing which it needs first, which here would be the i. It always starts there.

So i, Alex, is what? First time you hit the body of the for loop, i's value is?
>> Alex: 0.
>> Will Sentance: 0, array position 0 is?
>> Alex: 1.
>> Will Sentance: 1, instructions, Alex is really?
>> Alex: Multiply by 2,
>> Will Sentance: Multiply by2, and look at that people, we're able to use code that wasn't in the function when it was saved, we pulled it in.

That's pretty insane. Brand new what Alex?
>> Alex: Execution context.
>> Will Sentance: Execution context, into it we go. It's quite small here. What happens when I call stack Alex?
>> Alex: Pushing.
>> Will Sentance: Pushing the code multiply by 2, he's spot on. On to the call stack, multiply by 2, input over 1.

Into it we go. We're taking the array position 0 which is number 1, sticking it into instructions which is multiply by 2. That means that 1 is going down into multiple by 2. Therefore, Virginia, tough one, parameter, to which we're taking our 1 in, to what parameter is it assigned, Virginia?

>> Virginia: Input.
>> Will Sentance: Input, into input, excellent. There it is, input. Input by 2, 1 by 2, 2, return out, 2. Multiply by 2 input of 1, over by 2 instructions, multiply by 2 of 1 evaluated to, it becomes the output which is the number 2. What do we do with it, Virginia?

>> Virginia: We push it on to the output.
>> Will Sentance: We push it to output. The execution context deleted popped off the call stack, but it's a for loop, so we put up. We pop it off the call stack, we delete the execution context. And, but it's a for loop, so we're back again.

And this time i's value is what? Seth, at the back there, i's value at this time, Seth, is what?
>> Seth: 1.
>> Will Sentance: 1, well done Seth. Array position one is a number, what Seth?
>> Seth: 2.
>> Will Sentance: 2 [LAUGH], instructions is really what Seth?
>> Seth: Multiply by 2.
>> Will Sentance: Multiply by 2 is the input of two brand new execution contexts and our little local parameter into which the 2 goes.

No, that is horrible. Into which the 2 goes is, what's the parameter name Seth?
>> Seth: Input.
>> Will Sentance: Input, input by 2, 2 by 2 is 4, 4 gets returned out and stored, Virginia, into where?
>> Virginia: Output.
>> Will Sentance: Into output, it's a for loop there, 2, 4, 6. And we then finally Virginia return out what?

>> Virginia: Return output.
>> Will Sentance: Yeah, and I'm just going to say that I prefer everyone I prefer I mean, I, it's beneficial for your understanding to say, return not output because that gives you the sort of false impression that it's returning. When I hear output I'm at least thinking it's the label plus the value.

It might even be in my head the names of the label, and it definitely doesn't return the label. It doesn't even return the label plus the value, it just uses the referenced output here to evaluate that into a value. And that's what gets returned out. So I would instead help your mind think about it the right way and say return the value of output which is the array 2, 4, 6.

Do you wanna try Virginia?
>> Virginia: It would return the value of output which is the array 2, 4, 6.
>> Will Sentance: Fantastic, exactly, yeah, yeah, very precise, very nice, Virginia, there it is. People look at this. Only with a slight hint of irony from Virginia. Look at this people, copyArrayAndManipulate, at no point did it specify what to do with each element.

It did not say multiply each element by 2, but look at this. An array 1, 2, 3 became the array 2, 4, 6. [INAUDIBLE] We've created a brand new array 2, 4, 6. And at no point did we specify preset copyArrayAndManipulate to be multiplying each of element by2.

Instead, we were able to, when we ran copyArrayAndManipulate, we were able to edit. Because we had preset to leave a little blank, we were able to edit copyArrayAndManipulate. This starts to feel really nice. Already, if my goal of functional programming is each line is a little self contained unit with a nice English language label or English, human readable label.

Whose only consequence is in that line if I'm going to have to join those up again, hopefully I can join them up. This is our first example of composing. Just like you compose notes into a melody, composing individual blocks of code together, joining them up, enabling us to edit the functions we're saving.

We're essentially saying, copyArrayAndManipulate, leave bits of it TBD when you run it. Allow it to be reused in multiple different scenarios. We're gonna pass in divide by 2.

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