Check out a free preview of the full The Hard Parts of Asynchronous JavaScript course
The "Return Next Element with a Function" Lesson is part of the full, The Hard Parts of Asynchronous JavaScript course featured in this preview video. Here's what you'd learn in this lesson:
Will demonstrates how to create a function that holds both an array, the position current within a 'stream' of elements, and the ability to return the next element in the array.
Transcript from the "Return Next Element with a Function" Lesson
[00:00:00]
>> Will Sentance: We now have a situation here where we could create a little function inside another function, returned it out into a new global label and then use the new global label for that functionality, for what possible reason? Why did I not to find add to globally?
>> Will Sentance: Who already knows the answer?
[00:00:21]
Right? So I love it when there's lots of people feel, cuz I love the people feels, I love the people feels. It's gonna turn out when we return a function from another function we get so much more than just a function. We're gonna get a ton of what?
[00:00:39]
A single profound bonus, and that's gonna be critical for us to build out our own ITIL. Functions that when we call them give us our next element from our flow of data. And I might call them what a strange name. But instead give us our next element from our flow of data.
[00:00:59]
Let's see it here, so if you wanna create a function that holds, hold. You wanna create a function that has the ability to return our next element from a list of data, four, five, six for example. But then also, bundled on that function, it must have the underlying data to grab from, right?
[00:01:19]
Otherwise, where's it getting the data from? And it must have the ability to track which element it was on before, so that when we run that function, again it doesn't give us the odd element, the previous elements. How the hell is gonna do that? Cuz functions when they call do not remember their prior invitation.
[00:01:37]
They do not remember data created that was created in their prior running. The location you used on context, [SOUND] we run the function again, brand new function, add to created. There's no memory of previous running. So how can we have a function that when run, somehow remembers its previous running?
[00:01:51]
That it's been run before and had a previous element given out? We shall see, but that's what we gotta try and do. Gonna start with this calling create function that's gonna return out an inner function into returnNextElement. And then we're gonna hopefully get our first element, who knows how?
[00:02:13]
We shall see, all right, we're gonna walk through this very, very precisely because this is pretty much our main, really our only code on this whole section, but it's a very important code. And honestly, it can be considered quite hard for focus, especially who've not see in hot pots before.
[00:02:35]
Before you have, there might be a section that you remember that this is a sign to remind you of evolving something called a back pack. All right, good, line one, I would like to call this instead createFlow, because it's kind of creating the flow. We'll call it createFunction here createFunction, so what are we doing in line one, Victor?
[00:02:59]
>> Victor: We're creating a function called createFunction in memory.
>> Will Sentance: There it is, excellent, thank you Victor, next line James.
>> James: You're creating a new constant called returnNextElement.
>> Will Sentance: Excellent, do we know what it's gonna be yet? What's gonna be stored there yet?
>> James: Not yet.
>> Will Sentance: So it's gonna default in JavaScript to?
[00:03:18]
>> James: Undefined.
>> Will Sentance: Undefined, excellent, so here we go.
>> Will Sentance: I'm trying to get my board positioning right here. So returnNextElement is going to be output of calling createFunction, where we're passing the array 4,5,6, to it. We're gonna create what call, a new Local Execution context.
>> Victor: New execution context.
[00:03:47]
>> Will Sentance: New execution context, excellent, well done, man. I have the same enthusiasm for it as you. There it is, into it we go, and Sonny, what is, it has of course our thread. Our threads weave, winded its way in, and it has a memory just for stuff that's declared inside this function.
[00:04:07]
And Sonny, what's the first thing that is declared inside this function?
>> Sonny: Array, the array?
>> Will Sentance: Yeah, sorry, array, yeah, good, good job, array, yeah. Which is set to what? That's a parameter to what argument value?
>> Sonny: 4, 5, 6.
>> Will Sentance: 4, 5, 6.
>> Will Sentance: Thank you, that's very good, Sonny, and what's our next thing inside of our local memory?
[00:04:29]
Yeah, go ahead.
>> [INAUDIBLE]
>> Will Sentance: Set to?
>> Sonny: Zero.
>> Will Sentance: Zero, good, and Ben, next thing we set up in our local memory?
>> Ben: To clear the function inner.
>> Will Sentance: Excellent, there it is. Just so we can keep track of it, I'm gonna do it in a different color, because it is really weird, I recognize that.
[00:04:47]
It's weird to define functions inside of other functions and return them out. I recognize so I wanna make sure we're really keeping track of how that's evolving. Now that's the function called inner, are we gonna call it, Ben? We're gonna invoke it?
>> Ben: No.
>> Will Sentance: No, what are we gonna do instead?
[00:05:05]
>> Ben: We're going to return it.
>> Will Sentance: Return its entire definition out.
>> Will Sentance: Now there it is, out it returns, and store it where, Ben?
>> Ben: We're going to store it in returnNextElement.
>> Will Sentance: Exactly, return this element is now our function that was formally known as what, Ben?
>> Ben: Function [INAUDIBLE].
[00:05:27]
>> Will Sentance: See, how hard it is to keep track of this. It was formally known as that inner function. Inside a create function, it was known as Inner. Now, we've hit the return statement to create function, so all the labels in here, all the data in here, what happened to it?
[00:05:43]
>> [INAUDIBLE]
>> Will Sentance: Gone, just the function, they got returned out, parsed out to returnNextElement, perfect. We've popped all the Call Stack, and we're back out to returnNextElement. Let's just make sure we keep track of our Call Stack, our Call Stack, we're back in what execution context?
>> Ben: Global.
[00:06:03]
>> Will Sentance: Global, excellent, into Global.
>> Will Sentance: So we've done returnNextElement. Okay, so how can we, now in theory, what do we hope that calling the returnNextElement function's gonna do, in theory, Abdi? What do we hope in theory, Brian, it's gonna do?
>> Brian: Return four.
>> Will Sentance: Four, that's what we hope.
[00:06:25]
If we run it again it would hope it would return?
>> Brian: Five.
>> Will Sentance: And again? Six, and again, undefined at some point, yeah, okay. That's what we're hoping for desperately, cuz that allows us to rethink our collection of data as a flow. I run a function and get my x element, I run a function, get my x element, I run a function, get my x element.
[00:06:42]
That's a beautiful way of thinking of data. No more, I have a collection, statically, of data in memory. I've got to go and look at it, get an element, use it, look at it, get an element, use it. Now I just run my function and I've given, I've given my next element.
[00:06:57]
It's a really beautiful way of thinking about my collections of data as flows of element after element after element. Everyone got that mentality shift? It's a beautiful way of thinking. So you're right, it is to run, call returnNextElement, so let's do just that. So left hand side there of d says to do what?
[00:07:17]
>> Brian: Cast element one.
>> Will Sentance: Okay, element one is declared, yeah, good. Do we know what's assigned to it yet?
>> Brian: No.
>> Will Sentance: What are we going to have to do to figure out what is assigned to it?
>> Brian: We're gonna have to call it.
>> Will Sentance: Call what?
>> Brian: ReturnNextElement?
[00:07:34]
>> Will Sentance: Good, yeah, what symbol is, tell me, I got to call returnNextElement?
>> Brian: Parentheses.
>> Will Sentance: Excellent, retrunNextElement, call it, I get to create my favorite thing on Earth. So element one for now is undefined. I can call my favorite thing on Earth, everyone together.
>> Brian: Execution [CROSSTALK] [INAUDIBLE].
[00:07:55]
>> Will Sentance: Don't say local, don't ruin the phraseology A new?
>> Brian: Execution context.
>> Will Sentance: Yeah, I like that you to have a slightly tired tone. A kind of slightly exhausted please stop doing this tone, so you did great, all right so,
>> Will Sentance: There it is, it has a local memory in which we're gonna store anything that gets declared in here.
[00:08:23]
Now, we have to visually look back up to inner, but know that that's actually code here in returnNextElement. So let's maybe even write element = array[i] [i]++ returnElement. That's the code of returnNextElement. But we're gonna visually just save ourselves and just look up to inner, to know what it is.
[00:08:45]
So with that in mind, Shawn, what is the first line of code? Or what's the first thing we're gonna do inside returnNextElement? Left hand side first.
>> Victor: Create a const called element.
>> Will Sentance: Excellent, there it is, const called element.
>> Will Sentance: Element is going to be the eighth position of array, what the hell are these?
[00:09:06]
Well let's start to figure it out. Where do we look first for something that we don't have a? We're calling returnNextElements so it's goes in our Call Stack of course, there it is returnNextElement, we're calling it inside a Global. So inside of here right now, where do we look first for our array and our I Local memory, yeah?
[00:09:40]
>> Abdi: Sorry [INAUDIBLE].
>> Will Sentance: You're correct, very good, do we find them, James?
>> James: No.
>> Will Sentance: No, I'm calling returnNextElement to Global, so where might all my intuitions imply I'm gonna look next, Ben?
>> Ben: At the definition of [CROSSTALK] [INAUDIBLE].
>> Will Sentance: Okay, stop, stop the definition of what?
>> Ben: ReturnNextElement function.
[00:10:08]
>> Will Sentance: Definition, yeah, cuz you watch [INAUDIBLE].
>> [INAUDIBLE]
>> Will Sentance: All right, raise your hand if you know what are for? Cuz those are the people I'm gonna call on. You've never watched before? Okay, Rick, Where would everything suggest, I'm calling returnNextElements out. Where would everything suggest the next memories I look at?
[00:10:28]
I don't find it in this local one, where do I look next?
>> Rick: In Global.
>> Will Sentance: In Global, exactly. Into Global I go looking desperately for my array and my I, do I find them, Rick? No, so I get an error, right Rick? Is that my the answer's no voice?
[00:10:49]
>> Rick: [LAUGH]
>> Will Sentance: [LAUGH] Okay, I need to get better at that voice, right? No, that's not much better either, I get an error, okay, I get an error. Now that's, see that was more convincing, right? I get an error, hm yes cuz I looked for these, mm-mm, not there, hm, hm, hm.
[00:11:17]
There is another hard part where we focus mainly on this concept and I'd like to drag it out for long time. So we got an error on the horizon here, right?
>> James: How long do you want us to wait before we give you the answer?
>> Will Sentance: James has a sound of a confident person about him.
[00:11:36]
>> James: [LAUGH]
>> Will Sentance: Where is that array in I? Because I am certain, do not at any point think I can go back into my createFunction execution context. This has long gone. I cannot suddenly, I'll just go up a group and createFunction. That is long gone. So where's my red I?
[00:11:56]
All right, I'm not gonna drag it out anymore, it turns out, in case James shouts out the answer before I get to give the punchline myself. It turns out that as soon as I define my inner function, in side of createFunction, while I was still back in createFunction, before it exited.
[00:12:15]
As soon as I defined it, I got a bond to all the surrounding live memory, the surrounding data. You can call it state, you can call it the variable environment, the live memory, the data around the function definition. I got a bond to it, a little link, a reference to all surrounding data.
[00:12:35]
We'll talk about under what property in a moment. I gotta bond to surround data immediately. Meaning when I return that function out, I brought with it on the back of the function as the function got returned out, out on the back of it came all that surrounding live data.
[00:12:53]
When I return that function out, return out the function that used to have the label inner, into returnNextElement. On the back of the function, I brought all the surrounding data from when it was born. And it got stored in this new label, we will give it a new label globally returnNextElement.
[00:13:13]
But my surrounding data is attached to that very definition with the array literally in the memory as four, five, six. Not it will be, but literally store to memory. I as literally stored in memory as the number 0, and it's attached to the back of my function. There it is, on the definition itself, and so Ben was hinting this.
[00:13:38]
When I don't find array and I on my local memory, I do not go to Global immediately. Instead I go look at my definition of my function, I see is there a backpack of data that was brought out with the function, and look, there it is. And Ben, what do I grab?
[00:13:57]
>> Ben: You grab four?
>> Will Sentance: Correct, but specifically my array becomes, my array becomes
>> [INAUDIBLE]
>> Will Sentance: And my I becomes?
>> Ben: Zero.
>> Will Sentance: Zero, I'm not looking for my local memory, I'm looking on the function definition that's been called itself and there attached to it, is my persistent.
[00:14:21]
We'll give it a post in it in a moment, but my backpack of data from when the function was returned out from where it was born. As soon as it was born, it got a link to all the surrounding data from the memory in which it was defined.
[00:14:35]
When I return the function out, that bond didn't break. That bond pulled out on the back of the function all that surrounding data. And when I call that function by it's new Global label here, and doesn't find some, it refer to labels in defined data of in the local memory, it doesn't panic.
[00:14:55]
It looks first for the functions definition and finds attached to the function, our persistent live data from where the function was born. All right, which means exactly as Ben said, what am I storing in element?
>> Will Sentance: I'm gonna take the zeroth position of the array four, five, six which is, Ben?
[00:15:15]
>> Ben: Four.
>> Will Sentance: Four, and what am I going to do as my next line, Ben, inside my body of the function?
>> Ben: You're going to increment I.
>> Will Sentance: Right, do I find I in local memory?
>> Ben: No.
>> Will Sentance: Where do I go?
>> Ben: You go to the [CROSSTALK] [INAUDIBLE].
[00:15:27]
>> Will Sentance: Use my name, good, know my name.
>> Ben: [LAUGH]
>> Will Sentance: [LAUGH] Sorry, your name one and I go to one. And we then hit return, element which is really return, what?
>> Ben: Four.
>> Will Sentance: Four, we return out four into what Global constant?
>> Ben: Element one.
>> Will Sentance: Element one and look at that.
[00:15:49]
Look at that element one is not four, element one is four, exactly what we wanted From calling returnNextElement. Let's call it one more time to see what happens, and then we'll talk about what concept this backpack is. You may already know its posher name.
>> Will Sentance: Or, its more unintuitive name, or its name that I'm hoping is gonna be replaced with backpack in the spec very soon, I believe it will be.
[00:16:21]
All right, returnNextElement pop off the call stack, all of its execution context cleared, right? So we better not be having this information in here, cause it's all deleted. And we hit our next global line of code which is what, Eddie. Const element two declaring that in memory. Yeah, exactly, let's just try being super precise at our technical communication.
[00:16:46]
So I'll give you another shot on that. Yes.
>> Abdi: Declare the-
>> Will Sentance: Function.
>> Abdi: Declare the constant. Or declare the constant element to-
>> Will Sentance: Excellent. In global memory, and then we know it's going to be the return the value of calling what function? Albie?
>> Abdi: Return x element.
[00:17:05]
>> Will Sentance: Good, so for now, element two, or default two, everyone?
>> Abdi: [CROSSTALK]
>> Will Sentance: [INAUDIBLE], excellent. So let's create that execution context people, almost there, God I wanna have a sit down. Let's create execution context, in we go in our local memory. What's the first thing we declare, Victor?
[00:17:28]
>> Victor: Element.
>> Will Sentance: Element, which is going to be set to array, these mysterious array(i). What are these mysterious things, you might be asking? Well, where do I look for array and i first, Victor?
>> Victor: In the local execution context.
>> Will Sentance: Always in the local execution context first, nothing there though, right?
[00:17:51]
So, do I panic? No, I mean, I wouldn't panic anyway. Where might I intuitively look next?
>> Victor: You would intuitively go to global backpack.
>> Will Sentance: Right.
>> Victor: But there is a enclosed, [CROSSTALK]
>> Will Sentance: I like that sort of term, I like that sort of term. That's an enclosed backpack, good, got it, where I find array is four five six.
[00:18:14]
And I is?
>> Victor: One.
>> Will Sentance: One, our live data here persists that that's the function definition. It's persisting that the function definition in memory. So I is one, and so array is
>> Will Sentance: 4, 5, 6, and i is 1, because return its elements stored in global memory. So it's not suddenly deleting all the data attached to it at each stop.
[00:18:41]
It doesn't care about the running of this function except, what do you store in here. This is persistent data, just like return next element function is persistent function, as long as the application's running, it can't suddenly be deleted. So 2 is its attached backpack of data, persistent. That just means sticks around, it doesn't change.
[00:18:56]
Or it changes but it doesn't get removed. Okay, so position one vector of 4, 5, 6, is what?
>> Victor: Five.
>> Will Sentance: Five, good job. Five, and then we hit the next line inside the body vector which is?
>> Victor: Five, plus, plus.
>> Will Sentance: And over here we find it in the backpack and do?
[00:19:14]
>> Victor: 2.
>> Will Sentance: 2, and then we hit return, return what, Victor?
>> Victor: Return 5.
>> Will Sentance: Return 5, the value of element into element 2. Excellent, there it is, and look at that, I think that's pretty beautiful. We have a function now, that when born, got attached to its very definition.
[00:19:38]
The underlying state, the underlying data from which it's going to extract and return to us, on its call, one by one, the individual elements from that underlying collection of data. And it's keeping track of which one's up next using this little tracking value, also all bundled up on this return next element function.
[00:20:00]
I think that's very very beautiful, we'll talk about it in a second, but I think it's very beautiful that you can have a function return it's element that has everything you need. It has the ability when called, to return out an x element. It has bundled on it the underlying data, that it knows to extract from.
[00:20:17]
And it has bundled on it the information about what next elements are returned out, all bundled up in a single function. That's very, very beautiful design. All right, let's have thumbs, and one of the thumbs or medium might be, what do we call the backpack of data?
>> Victor: [LAUGH]
[00:20:36]
>> Will Sentance: Every time that you lost me, I'm clear, I have clarifications. Everyone's thumbs out and proud. Everyone knows what the backpack is called. No one has medium thumbs? All right. What's the backpack called?
>> Victor: Good, good job, Alec.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops