Welcome back.
Now, why you'll learn in the next few videos is quite advanced.
It does take some time to really grasp the concepts and understand them, and the best way to do that
is to do these yourselves.
So use these videos as a reference to come back to when you have questions.
I'm going to cover the main topics that you'll see out in the wild.
You can come back and reference these videos whenever you have questions.
And in this video, we're going to tackle advanced functions.
Now, I have a simple function for you here, but knowing what we learned about the new JavaScript syntax,
we're going to convert this first to how we should write JavaScript function.
Word is gone now, we can just say.
Consent first equals.
Arrow function.
And this error function has a great which can be a constant and a function.
Which again, can be Konst second.
And finally, this.
Can be a cost as well.
We also learned about scope, an important property of function is that the variables create inside
of them.
Including the parameters are local to the function.
So that means that every time we run the first function, this block of code gets executed and the great
variable gets created every time.
Now this is actually good for us because we make sure that if our program, every time we run first,
remember degreed well, it'll have conflicts because it's a constant and we constantly reassign the
same thing to a variable that already exists.
So this way, within a function, we make sure that every time we run it, it's a clean slate.
You can name the variables however you like because there's nothing else that will collide with it.
Like I said, this behavior helps prevent accidental interferences between functions.
And as developers, we want to minimize the number of bugs or errors in our code.
If all variables were shared by the whole program, it'd take a lot of effort to make sure no name is
ever used for two different purposes.
Imagine if Grete was in another function, and we had no idea.
And we can't use it.
Well, luckily, by having our own separate scope, we're able to make sure that we can use Grete without
having to check the entire code base.
Now, by treating function, local variables as existing, all within the function, the language makes
it possible to read and understand functions as small universes, where whatever happens in that universe
only matters to itself.
But I also wanted to demonstrate an interesting concept with JavaScript, and that is closures.
You can think of it as this a function runs the function executed.
Now it's never going to execute again.
Kind of like the first function.
We just executed it here.
And the result we put into new function.
It's going to remember that there are references to those variables alive in a memory first.
However, we see a problem here.
You see that when we load up this program on our website, the JavaScript engine will see this.
I'll say, OK, we have a variable first.
That's a function.
Great.
And then in the next line, we see, Oh, we want to assign variable new function and we want to get
the result of first.
So the program runs first sees that we want to create a constant great high.
And then we also see that we have another function called second, and we're returning that function.
But there's a problem here, right?
Second, needs to remember what grit is.
Although first runs and returns second.
So you can think of this as once we do this, we will only have the second function.
Now, and I know this is this looks confusing, but just look at the highlighted here.
That's what calling first meets.
But you see over here that the greet variable second doesn't.
Well, it's not within the scope of second rate.
What closures does and this is a rule in JavaScript is that the child scope always has access to the
parent's scope.
So it's almost as if it remembers.
They always remember that there's a reference to those variables alive.
So inside the web browser, the web browser says, Ah, this second function needs greet, so I'm going
to remember it.
Let me demonstrate that for you.
So if I do, first here?
And I'm going to copy this into the console.
And now we have new function.
If I run new function.
I get high.
Even though first is never going to be a run again.
The only thing that we have left is the second function the Web browser remembers Greet.
Again, this is a confusing concept when you hear for the first time.
But like I said, just remember closures.
Is just saying a function ran the function.
Executed.
It's never going to execute again.
But it's going to remember that there are references to those variables, so the child scope.
Always has access.
To the parents go now, you may be wondering if I did hear Konst name because Bobby.
Will the first function have access to who, Bobby?
No, it wouldn't.
So think of it this way.
Children always have access to their parents scope, but parents go.
They don't have access to their children.
All right.
Let's get into a few more things.
Next, we're going to talk about currying.
And caring is the process of converting a function that takes multiple arguments into a function that
takes them one at a time.
Let's see what I mean.
We have a function here.
We'll call it multiply and multiply accepts.
Two parameters.
And again, we're using our new functions index will say A Multiplies B.
Now, currying means we're changing this function to only accept one parameter at a time.
So that means we do.
Curried multiply.
Equals.
A B.
A times B.
Whoa, whoa, whoa, whoa.
What did we just do?
And again, this looks very confusing, but think of these arrows as functions.
So right now, if I do carried.
Multiply.
And I'll just say three.
But let's see this in action, what happens?
I get a function that accepts be multiplied by.
So by running, this is saying that a is three.
And now we'll know that when we multiply a history.
But because this has a function and another function, so a function inside of a function, this just
returns this part, so it returns a function.
As you can see here.
So now, in order to make this work, let me put this back.
In order to make it work, we have to say curried.
Multiply.
We'll say three and then another bracket for.
And I get 12.
If we look at this function compared to here, we see exactly what we did.
We created a variable COVID multiplier that accepts a parameter, so it's a function that accepts a.
In this case, it's three.
And once you call that function, once you've run it, it returns another function that accepts B and
that function multiplies A and B.
So what I'm doing here is saying create a multiplier.
A is three.
B is for and now multiply a times B.
And as you can see, as I said about currying, it's the process of converting a function that takes
multiple arguments, like I said, into a function that takes them one at a time.
Now, why do we even need to do this?
Because now it's more extensive, all I can do something like cost multiply by five equals.
And now I have this.
So any time I want to multiply by five, I could just say, let me copy this.
Now, any time I want to multiply a number by five.
Five.
Ten.
And now I have this function that was created that always multiply things by five.
Which is very cool.
All right.
We're going to get into one more thing and then I promise I'll make your head stop hurting.
It's called compose.
And compose is the act of putting two functions together to form a third function, where the output
of one function is the input of the other.
Even me saying that, I'm like, What did I just say?
So let's write this down a compose.
Looks like this.
Let's say F and G parameters, FMG return a function.
That takes parameter A. That returns a function that has.
This.
Holy Moly.
And if you look at this and you have no idea what's going on, this is something that takes years for
some to get.
It is really, really advanced stuff.
But.
If you're able to understand the inner workings of this, you can pretty much do anything.
Let's let's give it a go.
What is happening here?
Well.
It looks like looking at F and G, it looks like F is a function because while we have the brackets,
it even highlighted in blue for you and G is also a function.
If I had a sum function that that, let's say, takes a number.
And just.
Adds one.
What we can do with compose is, I can say compose again.
We have the function here, some some.
So both FMG are some.
And now, because it takes another bracket, I can say.
All right.
So let's run this and then we can go step by step to show you what it does.
I get seven.
So why is that?
Well, let's take it one by one.
If both F and G are some and A is five.
We look at what the function returns, and because again, we have two brackets, we're executing the
first part of the function, which returns us another function, which is this and within it, we give
the a five.
So when this function runs, it says A is five.
OK, and then let's run the inner function G.
In this case, it's some.
So if you remember, some is just saying, give me five and then five plus one.
So now this changes to six.
And then finally, the F function runs, which is again, some.
And this, says some, is giving me six.
So six plus one.
Is seven.
And this whole thing returns seven.
Well, all right.
There was a whole ton of stuff.
But I want you to remember these three key words, because when you get to advanced JavaScript functions
are really, really important.
You'll hear words like closures and currying and compose a lot and you'll find tools and libraries that
use these heavily.
Now you don't need to know the definition of them.
You just need to be able to read a piece of code and understand what's going on.
And this is why I like showing you this, although it's really advanced and very hard to to grasp by
understanding the step by step process of how a function works.
This is really useful because now when you encounter this in the wild, you'll understand how everything
works.
Now, to finish off this function section, I want to tell you the most important thing that you can
do as a web developer when creating code.
And that is the idea of avoiding side effects.
And functional purity.
What does that mean?
Well, let's go back to my diagram here.
You might remember this from the first part where we said a input is what we give a function input of
some sort.
It could be an empty input or it could have parameters like five or 10.
A function does something that we define.
It has its own scope.
Remember, it's its own universe.
It could have console.log.
It could do a bunch of stuff.
And then it asks, Am I returning anything you can?
This should be undefined.
So you can return a value or if it doesn't return anything, it just does.
Undefined.
Now, the two words that I just said side effects and functional purity.
Well, side effects are any of these things, any of actions that happen?
Inside of the function that we don't really know anything about, if it interacts or reads or writes
to an external variable, for example, or console logs.
Well, that's a side effect.
If we change here, a variable one equals one.
And then I have a function.
That changes a.
Well, that's a side effect, that's something that the fonctions doing to affect the outside world.
Remember, we want to think of functions as its own universe and if it starts affecting the outside
world.
I mean, it's not the end of the world.
We've done console.log before we've done.
We've done this before.
But it is good practice to avoid these side effects.
And by avoiding these side effects, we have something called functional purity and functional purity.
Is a concept where we say in order for us to write really, really good programs, we want to avoid.
Side effects.
And we always wonder.
Return.
So that this and this are gone.
And we always return something.
And what's the power in this?
By avoiding side effects.
And always returning, we create something that we call deterministic and deterministic is a word that
you may have heard.
It means that no matter what, if my inputs, let's say five and 10, go through this function, this
little universe, the return value will be always the same.
Let me say that again, the input, whatever we put in the parameters, whether it's empty or it has
certain parameters.
It always returns.
If we run this a thousand times, it always returns the same value.
That's determinism.
It's a very important concept, and that's a key principle in avoiding bugs, because if this function
always does the same thing well, then you know exactly what it does and you won't have random errors
popping out here and there.
That's what I want to leave you with.
Although this is not the law and you'll find code bases that will have a lot of side effects, there's
going to be a lot of things happening inside functions that maybe even effect variables that live outside
of a function.
It is a really, really good practice to be a top performing developer to have this in mind of creating
functions that minimize side effects.
And have functional purity, what we call determinism, where anything you put into the function, it
always returns the same thing.
All right.
That's it for now.
Go try out some exercises.
I'll see you in the next one.
Bye bye.