JSJ 469: The Case for JavaScript Iterators and Generators, part 2

This is the follow on to the episode first recorded regarding JavaScripts iterators and generators. Dan takes the lead and picks up from last time. The panel discusses how JavaScript uses and implements iterators and where people are likely to see them. Then they dive into generators and briefly discuss the concept and their uses.

Show Notes

This is the follow on to the episode first recorded regarding JavaScripts iterators and generators. Dan takes the lead and picks up from last time. The panel discusses how JavaScript uses and implements iterators and where people are likely to see them. Then they dive into generators and briefly discuss the concept and their uses.
CODE:
  • x = {[Symbol.iterator]() {let i = 0;return {next: () => ({done: i >= 10,value: i++})};}};
  • for (const v of x) console.log(v);
  • console.log([…x]);
  • console.log(…x);
  • function* g() {for (let i = 0; i < 10; ++i) yield i;}

Panel
  • AJ O'Neal
  • Charles Wood
  • Dan Shappir
Sponsors
Links
Picks
Sponsored By:

Transcript


CHARLES MAX_WOOD: Hey everybody and welcome to another episode of JavaScript Jabber. This week on our panel, we have AJ O'Neill. 

AJ_O’NEAL: Yo, yo, yo. Coming at you live from beautiful sunny Virginia. 

CHARLES MAX_WOOD: Dan Shapir. 

DAN_SHAPPIR: Hi from Tel Aviv. 

CHARLES MAX_WOOD: I'm Charles Maxwood from devchat.tv. And yeah, this week we're going to do a follow-up on the iterators and generators discussion you guys had last week that I missed that I'm kind of sad I missed. Dan, do you want to just give us a little bit of context there so that we can kind of move ahead from wherever we left off last time? 

DAN_SHAPPIR: Sure thing. Like you said, it's a continuation of the previous episode, and I highly recommend that listeners listen to that one first. So if they haven't, then they should pause now and listen to it. But to give a really brief overview, we started a discussion and a debate about JavaScript iterators and generators, or more precisely, iterators and generators in JavaScript, since this is a construct that is available in other programming languages as well. We talked about what iterators are, what is their purpose, enabling sort of a decoupling between containers and the algorithms that can operate on them. And I also described how iterators are implemented in JavaScript. And then we kind of debated whether their addition to JavaScript was in fact worthwhile, or whether it was just too late in the game. 

 

This episode is brought to you by Dexecure, a company that helps developers make websites load faster automatically. With DeckSecure, you no longer need to constantly chase new compression techniques. Let them do the work for you and focus on what you love doing, building products and features. Not only is DeckSecure easy to integrate, it makes your website 40% faster, increases website traffic, and better yet, your website running faster than your competitors. Visit decksecure.com slash JSJabber to learn more about how their products work. 

 

DAN_SHAPPIR: To give a really quick, brief explanation, because it really is very simple Iterators in JavaScript are basically just an object that has a next method. So any object that has a next method and that next method returns an object that has two fields. Done field and a value field. The done field indicating whether or not you finished iterating over all the items. And the value, if done is not true, if it's false or falsy then value contains the value of the current item in the iteration. So any object that implements that can be used as an iterator. That's it. So the implementation is actually very, very simple. I also explained that in order to get the iterator for a particular collection, that collection or object needs to implement a method whose name is symbol.iterator. And I'm actually going to do something that we usually don't do because the code is so simple. I'm actually going to post some code into the show notes that actually shows how this looks like. So this is basically what you would need to write or to get an object that provides an iterator that just counts from zero up to nine. And as you can see, it's all of what? Eight lines of code. It's really, really simple. So the implementation of iterators in JavaScript is really simple and doesn't really break the language in any way. It's totally integrated with how JavaScript works. And obviously you can also just write your code that operates directly on top of iterators. So you can obtain an iterator and then keep on calling next in a loop until you get to the one that returns the done with true and then you stop. But JavaScript actually provides some constructs that actually make it even simpler or easier to loop over iterators. But before I explain those, anybody have any comment or anything so far? Okay then. 

AJ_O’NEAL: Look, oh, I was just gonna say, looking at what you pasted, this looks really..Simple, it is a little bit different from what I understood. So it's not that the object has a next method. It's that the object has a symbol.iterator method, which is a really weird way to name something for people that are used to just using strings. I mean, looking at it, I get it, but only because I've seen other people do it. Otherwise I would have no clue what that meant. But okay the key of the object is symbol.iterator. That's a function. It returns an object that has a next function. So it's not an next function on the object itself. It's a next function on the object that's returned by the symbol.iterator function on the object. 

DAN_SHAPPIR: Yeah, again, in the code example that appears in show note, X references not the iterator itself, it references the quote-unquote collection. Or in this case, it's an object that represents a collection. It's actually just a sequence of numbers. And symbol iterator, whenever you call it, you get back an iterator on top of that object. So x itself is not the iterator. What is returned by symbol iterator is the iterator. 

CHARLES MAX_WOOD: Right. So just to give a little bit more concrete example here, what we're talking about is we've got like a phone directory. Right? You know, remember the old books that used to send it? Anyway, yeah, I'm old. Anyway, so, but yeah, so you could have a phone directory object, right? That has a list of phone numbers and people's names in it. And then it's also got this iterator attribute to it that tells it how to move through the collection of phone numbers and names. 

DAN_SHAPPIR: Exactly. And in fact, all the JavaScript built-in collections actually do that. So, arrays implement a simple iterator, which iterates on top of the arrays, maps and sets, the new collection types that were also introduced in ECMAScript, also implement iterators that you can get to. And by the way, a node list also implements an iterator. So you can actually use for all over a node list. So that's an easy way to actually iterate over a node list where previously it was, you know, not as pleasant potentially. So now if you want to actually iterate over the X, so like I said, you can invoke the symbol iterator directly and then call next directly, but you don't need to do that because for all actually does it for you. So again, I'm posting a one liner bit of code which actually shows how this looks like. So this really just does that for you. So when you have for of it actually retrieves that iterator and then uses it and puts the value into the V variable and then just logs the V. And again, I apologize to those who are just listening and can't see the show notes. Please do look at the show notes. But it's basically it's 

CHARLES MAX_WOOD: pull your your car over before you do that. 

DAN_SHAPPIR: Yeah. But it's it's really, really simple code. You know what? I'll just read it out. It's for open parentheses const v of x, close parentheses console log v. And x is the object that represents, that has the iterator and v just gets the values. So it does all the quote unquote heavy lifting of checking the done and getting the value into v and so forth. But you know, it's real overall, it's just obscuring really simple code. Now the alternative way to get it all the values of the iterator is to use the spread operator. And you can just, the spread operator is that the new dot dot dot operator that also exists as part of x or equoscript. And you can do something like that. You can do a console dot log, open parentheses, open square brackets, dot dot dot x, close square brackets, close parentheses. So you basically just copied all the elements of that iterator into that array. And then I just log the array. So it achieves the same effect. And finally, the last thing, and this is the last bit of code for now. The last thing that you can do that I actually neglected to mention in the last episode is that you can actually use the spread operator directly on arguments into a function. So if I just want to log all the items in that collection, all I need to do is just, I don't even need to put it in an array. I can just spread it directly into the argument list and that just works. So yeah. Any, anything so far? AJ, are you okay with this code AJ? Do you approve? 

AJ_O’NEAL: Let's not talk about that. Let's move on. 

CHARLES MAX_WOOD: I have a question here just to kind of bring some of this home and that is, I'm looking at this and I'm thinking to myself and I have some answers in my head, but I'm kind of curious what the conventional wisdom is. Where would I ever use this? Right. Because it's one thing to know that JavaScript does this. It's another thing to be sitting here and going, Oh, well, I could totally make my life easier by using this right here. So, so where are people actually using this? 

DAN_SHAPPIR: So as I explained also in the previous episode, very, very few developers actually implement iterator, but quite a number of people actually use iterators because whenever you use for all you're using an iterator. And almost whenever you're using the spread operator, you're using an iterator. So I would say it this way. People who are supposed to or who should be implementing iterators are people who are implementing libraries or frameworks or APIs. So if you want to implement some sort of API that provides the functionality of iterating over something and the perfect example would be the node list that is exposed by the DOM API, then iterators are for you. But in most cases, most JavaScript developers would just be consuming them whether they know it or not. And that's actually, from my perspective, the beauty of iterators, that thanks to for all and thanks to the Sprinter operator, they're actually really easy to consume and you don't really need to understand the mechanics of how they operate. But you know I always believe that if you know, you should be curious about what you use, but you don't have to know. 

CHARLES MAX_WOOD: That makes sense. One other question I'm also thinking about here is, can you set up multiple iterators on the same object? I'm kind of envisioning like in the phone directory, right? Maybe you have a private list and a public list, right? And so you have an iterator for private and iterator for public. Or do you just do you have to create two different objects in order to get two different iterators?

DAN_SHAPPIR: Well, what they actually did in the case of a map is that you have different functions to return different types of iterators on top of a map. So in the map, you have your mapping keys to values. So you could iterate over the keys, you can iterate over the values and you can iterate over both. So they actually have map.keys function and a map.values function and a map.entries function. iterate that makes sense. Yeah. So that would be how you would go about something like that. 

CHARLES MAX_WOOD: Awesome. 

DAN_SHAPPIR: So this kind of explains iterators and is more or less where we stopped the last time. And as I said, the construct itself is really simple and doesn't really extend the JavaScript language. Kind of like with promises that are just objects that have a then method that we only really extended JavaScript the language when we added a sync and a wait over functions and over function calls in order to actually leverage some of the capabilities of promises and make them potentially easier to use. And as we will see, the same sort of thing happened with iterators. But before I get there, I actually want to take the next step with iterators which in my opinion actually makes them more useful and interesting. And that is talk about asynchronous iterators. So asynchronous iterators really take iterators to the next level. A regular synchronous iterator, the next method returns an object that has a done field and a value field. Can you guess what the next method of an asynchronous iterator would return? 

AJ_O’NEAL: Reject and resolve. 

DAN_SHAPPIR: Exactly. It returns a promise. So it returns a promise that resolves to an object that has a done field and a value field. So it's really in terms of the technicalities, it's really a relatively minor step, it seems. It's just instead of just directly returning that object with a done and value, you return a promise which resolves to an object that has a done and value symbol.async iterator or? Exactly. So you also get the asynchronous iterator instead of calling symbol.iterator to get it. Uh, you need to call symbol.async iterator in order to get it. That's the other difference. And here's why it's such a, even though it's such a small change, the consequences are so significant in my opinion, because now I can actually implement something that iterates over a sequence of events in time. A regular iterator iterates, I like to say, in space. You're either iterating over the values that already exist within a collection, so you're iterating over the space of memory, or you're generating values, but you're generating these values synchronously. So again, you're iterating in space. With a synchronous iterator, you're iterating in time because you're waiting for events to happen and you don't progress until the next event in the sequence either resolves, that means happens or rejects, which means that it's failed. So an example might be I'm downloading data and the data is arriving a packet at the time. I can implement an asynchronous iterator over that and whenever a packet arrives, then the promise resolves and the value would contain the content of that packet and done would be true as long as more packets are arriving when the last packet arrives, then afterwards done will be false. And that means that I can actually write my code that iterates over this asynchronous stream of data like a for loop. It just looks like a regular for loop. It's just that instead of writing for of, I write for await of. So it's for await, open parentheses, and then the rest looks the same. And it's a really, really powerful construct, in my opinion. I'll give an example. Think about it this way. When we write server-side code in Node using Express, and we want to handle the incoming requests then the way that it works is you specify callbacks. And the callbacks are invoked whenever there's a new request and the callback gets a request and response and you can read the data from the request and then you write your output into the response. Well, now I can write it as a loop. I can write for a weight of, and I treat these requests that are coming in like it's just, it looks like a loop. Initially, it seems really odd and strange, especially to anybody who's kind of used to the way that things are in Express. But if you think about it, it's actually a better mental model that represents what's going on because the server is really iterating over requests coming in, handling them one at a time. And I think that Deno, or Deno, sorry, actually implemented this way. So like I said, it's a really powerful construct and a mechanism for dealing with sequences of events. And there's actually an additional really powerful consequence of that. But before I go there, any comment or thoughts? Would you write your server-side code that way? 

CHARLES MAX_WOOD: I'm still trying to wrap my head around it. And I think I get the basics. And since it's asynchronous, I guess it just waits for the next thing to come in until done is false, right? Yeah, I guess that makes sense. I don't know. I don't know if I would actually write my code that way or not. 

DAN_SHAPPIR: Again, I think that in a lot of these cases, it's a question of what we're used to. 

CHARLES MAX_WOOD: Yes. 

DAN_SHAPPIR: What we're used to may not necessarily be the ideal representation. If I was if I'm coming into JavaScript as a totally new developer, I might write the code differently than I write it now because you know, that's the way I'm used to doing things for the past 10 years. 

AJ_O’NEAL: I think that the way that express works as it stands today is wretchedly terrible. I love express. I think that express is really awesome, but it's terrible for asynchronous processes because it relies on the next paradigm and that is just so awkward to mangle into a promise paradigm. So the promise paradigm didn't exist when Express was created, or it wasn't standardized, there was talk of it, but it wasn't something that like, if you used what a promise was back then, it would not be compatible with what a promise is today. So I would love to see something that has the simplicity and the cognitive ease of use of Express, but with a simpler and more cognitive, easy to understand method of dealing with asyncrety, like the way that...You know promises give you and to some extent if you understand promises that await async can give you if you already understand promises and I and I see I see now from what you're talking about because you originally raised this mini discussion with me on twitter in regards to me posting an updated version of my my old Walk.js module. I was I wrote I wrote the first walk module for node, but I wrote it really looking back at it convoluted because I was trying to use event emitters because that was what node was touting. Streams were event emitters and everything in node was event emitters and that was the paradigm. And again, promises weren't around yet and async wasn't exactly thought about the same way in terms of the way that people were blogging about it and talking about it. And I think it was overcomplicated just in general, the way that we were thinking about things back then and the promise paradigm is much simpler. And I can see how, you know, using a, a four of on an iterator could also produce very elegant code. Although that said, I'm not going to go back and, and change what I wrote now. Cause I think equivalently it works equivalently well. Maybe I could add something to it to make it work better for that. Cause I'll reinvestigate it, but yeah, I see, I see how this can give convenience. 

DAN_SHAPPIR: I would also add that, you know, JavaScript is intentionally and inherently a multi-paradigmatic programming language. So some people prefer to use it in a functional style and then they kind of chain operations together. And some people prefer to use it in an imperative style and they prefer writing for loops. So the beauty of async-await in general and, you know, for-await in particular is that it enables you to write really straightforward imperative code that takes advantage of these underlying functional capabilities, I would say. 

CHARLES MAX_WOOD: So for a weight and async a weight work the same way, right? And if I remember right, they return a promise. 

DAN_SHAPPIR: Yeah. The difference is that with a weight, you just, you know, the argument, you just you do a wait something and that's the assumption that the something is a promise and then you're kind of blocked quote unquote right until that promise either results or rejects with four weights. This is kind of what happens in the loop that each iteration of the loop the iterator returns a promise and then you're blocked on that promise and then when the promise results. If it's done, the loop is just done. And if it's not, then you've got the value and you use that value within the body of the loop. 

CHARLES MAX_WOOD: Right. 

AJ_O’NEAL: So one of the kind of Achilles heels of nodes has more or less always been streams. And one of the biggest problems is the push ideology versus the pull ideology, meaning that with a stream, you get a data event and you must handle it. Or at least that's the way most people think of it. This was actually changed like five years ago, but I don't think hardly anybody knows that, and that's, it's a terrible way to do it because your, your Ram will get overloaded. If, if you're building some sort of application and you can't write to disk or write to the network fast enough, you're just getting data event, data event, data event, data event, until you run out of memory and your program crashes. And especially, you know, when things are running in, you know, cloud architecture where you're only getting 512 megs of RAM, that's problematic. And that's the push methodology. As you get an event, you must handle the data. The promise methodology is kind of in the middle because you can get, say, the data event, but if you were able to return a promise, which would be awesome if Node is updated to work this way, and maybe it is already, but I don't think so, then you could say, okay, well, don't give me another data event until I resolve the promise. But then the pull methodology is I will tell you when I am ready for a data event. And this is the way that Streams 3 work in Node is that you can call, I think it's.read. And it's like what you're describing with the generator or the iterator, sorry, not the generator, the iterator where you can call.next. And so you can say, I'll let you know when I'm ready to get the next packet of data. And then you're leaving all of the management of the buffers and all that down to the TCP layer in the network where it belongs or on the file system layer in the operating system kernel, rather than bringing all of that complexity into your application where you're probably not equipped to handle it. And you probably don't want to handle it there anyway, because the other layers already handle this very efficiently and very well. So I can see how if you're using this iterator pattern for something like network streams file streams, basically any type of stream. If you use this iterator pattern you give your end user the flexibility to decide whether they want to have the feeling of a push pattern, but you give them the security because it's a promise. It can look like a push pattern, but it's not going to overload with data because you have to resolve before the next piece would come in. Or you can give them the ability for it to look like the pull pattern because they can call that next. And both use cases are handled equally well. And I think that that is elegant.

DAN_SHAPPIR: I agree. The next gives you another level of control. The only issue is that for the majority of JavaScript developers, next is actually obscured by the use of for of or for a wait of. You don't actually explicitly or manually use the next. 

AJ_O’NEAL: But you can. 

DAN_SHAPPIR: But you can.  So...You could say that if I'm an experienced developer and I want to have greater control, then I would explicitly use the next. There's actually even an additional capability here that I'm not even going to go into because it's beyond the scope of our discussion today. It's like a rabbit hole that you can, you know, literally drown in. But our friend, Kyle Simpson, Getify, actually wrote a nice blog about it recently. He's creating a library using it. You can actually pass parameters into next, and then you can create this sort of a two-way data exchange between the code that consumes the iterator and the code that runs within the iterator. But again, I won't actually go there. 

AJ_O’NEAL: Well, I do want to know one thing on that. Is this something that is part of a standard or is this like ad hoc crafting engine-ness? 

DAN_SHAPPIR: Both, kind of when we get to generators, again, I might mention it again, but it actually leverages that capability for those who are sophisticated enough to use it, but it's hardly used because, again, use of next is usually obscured. And then you don't actually explicitly use next, and consequently you can't really explicitly pass arguments into next. So again, it's this sort of a weirdness that might be applied in really sophisticated scenarios. You know, the most I've hardly ever seen this done anywhere in production. Yeah. 

AJ_O’NEAL: Well, I, to be honest, I think anybody looking at that symbol dot iterator stuff, it's not that it's complicated, but it looks unfamiliar. 

CHARLES MAX_WOOD: Yeah. That's a good way to put it. 

AJ_O’NEAL: I wouldn't want to put it in code that I think I'd want to share with other people where they'd want to look at the code because I would like, unless it was really, really, really beneficial and really necessary because I wouldn't want them to be, because it looks unfamiliar and it's kind of difficult to explain. I don't know that I'd wanna, and I'm just fumbling over myself. I'll just stop. 

DAN_SHAPPIR: No, but I totally, sorry Chuck, go ahead. 

CHARLES MAX_WOOD: No, all I'm saying is, what I'm hearing from AJ is, is that it's a readability issue, right? Somebody's gonna stop and stumble a little bit going, what is symbol.iterator? And then have to actually reason out that you're creating your own iterator for whatever object you're dealing in. And so to that degree, yeah, I kind of get it. But Dan, you specifically pointed out that the people who are most likely to use this are writing frameworks and other libraries and data types. And so it'll be pretty opaque to them that this even exists because they're just going to be consuming it on the other end. 

DAN_SHAPPIR: Exactly. But as we will see in a short bit, generators were actually created as an attempt to simplify the creation of iterators and whether or not they were successful in doing so, you can tell me what you think. But we'll get there in a minute. I just want, before we do get to generators, I just want to add one final piece to this asynchronous iterator thing. It turns out that there's this interesting twist in the implementation of for-await. For a weight, it uses a simple dot async iterator to get the asynchronous iterator of what it's iterating over. But if the object that it is iterating over does not implement simple dot async iterator as a method, it actually looks for a simple dot iterator in order to obtain a regular iterator and use that instead. So it uses a regular iterator as a fallback to the asynchronous iterator. Now that seems fairly simple and not really consequential, but it turns out to have a really interesting implication. And the implication is that I can use for a weight of to implement functions that perform various algorithms, like a search, like a filter, like a sort, or max, or whatever, or sum. And then I can provide them as input, either an object that represents an asynchronous stream or a regular synchronous collection. And the same function and the same code can work in both cases. So you can actually implement a library of algorithms that works both over an asynchronous sequence or a synchronous one. I could use the same filter function to filter elements in a collection or to filter events in a string, which I think is really powerful and again, a really big missed opportunity on the part of JavaScript that it does not implement or does not provide such a library of algorithms. In fact, I think it's such a missed opportunity that I actually implemented such a library myself and wrote a blog post about it. And again, here's a link for the show notes. And the code for that library is really small. You need to potentially if you're interested in the implementation details, some of the code is not trivial. And like AJ said, you need to like think about it and reason about it because it's unfamiliar, but it's actually very short code the whole of the library is something like 200 lines of code. And I provide a filter and a map and a flat and whatnot, and they can all work both on collections like arrays and on data streams, which again, I think is a really powerful abstraction. 

CHARLES MAX_WOOD: I like that. It also, like you said, I mean, you know, if you can do it in a few hundred lines of code, it really does make it so that it's I guess it tells me that it is rather approachable if I take the time to understand it, but it's also easy enough to abstract to somebody who doesn't need to understand it. 

DAN_SHAPPIR: Exactly. And the performance overhead is really low because it's such a small download, for example, if it's, let's say, browser side. And that more or less concludes the portion on iterators, so now that we can move over to generators. And generators are about implementing iterators. Now, as we've seen, the code to actually implement iterators is actually fairly small and straightforward, but the people who created or added this into JavaScript actually thought that it's potentially still a bit too complicated for most. If you look at the code example that I gave, you need to make sure that you put the counter in the right place. If you put it to low in the nesting of scopes, then you'll get the same value zero for every iteration. If you put it too high, then you can potentially share the same counter between multiple iterator instances. There are a lot of ways in which you can actually make mistakes in this code, and it's kind of nested. You've got an object and a method within the object and an object within the method and another method within the object. So it's not as potentially as nice as it might be. So they were looking for a way in order to simplify the creation of iterators. And the solution that they came up with are generators. And generators look like functions. They use the function keyword, but then they have this asterisk at the end of the function. Now I can't say that I'm in love with the syntax because I'm not. It's like this is a function sort of, I'm putting an asterisk on it because it's not quite a function. And then it's interesting. 

AJ_O’NEAL: For the ECMAScript functions that don't have the keyword function, is it just an asterisk? Just asterisk and that's it. That's your function? 

DAN_SHAPPIR: To be honest, I've, I've, I, you know, I think there's a way to do it with, uh, with the arrow, but I'm, don't remember the syntax off the top of my head. And I hardly, I don't think I've ever actually done. It's probably doable, but I don't remember what the syntax weirdness is in that case. Or maybe it's not doable. I don't recall. Anyway, and again, I'm going to post the last bit of code for the show notes with, which is how the generator would look for the exact same example that I gave as using the manual implementation. So it would look something like that. It's basically function with an asterisk and then I just implement a for loop inside of it and I do a yield. Yield is a new keyword that you use to emit values out of the generator. It's kind of like the introduction of the await keyword and like you can only use await within functions that are defined as asynchronous. You can't use await within a function that isn't asynchronous, that doesn't have the async keyword. Likewise, you can only use a yield within generators. You cannot use yield within a regular JavaScript function. Now, here the weirdness begins, because if you... 

CHARLES MAX_WOOD: I love the way you put that. 

DAN_SHAPPIR: Yeah, if it wasn't weird enough, here the weirdness really begins, because if you invoke the function G, it doesn't actually run the code that you have in G. The code does not execute at all. So if I do the generator that I gave the code sample to is called, I just gave the name G, but if I do a G function call, you would expect the code in G to run, but that's not what happens. Instead, you immediately get back an object, and that object provides an iterator. So you get back an object kind of similar to the object that I manually created and put into X in the previous code example. So you might ask yourself, when does the code in G actually run? And the answer is that it runs the first time you call next on an iterator. And it runs until it reaches yield. And then it takes the value that was yielded and provides it through the next. So it's the value that you get in the done value pair. That's the value that gets put into value. Weirdness. 

CHARLES MAX_WOOD: Yeah, that's interesting. 

DAN_SHAPPIR: Now, the other is... 

AJ_O’NEAL: And this was to simplify iterators, you said?

CHARLES MAX_WOOD: Thank you. 

DAN_SHAPPIR: Well, look at the code of the generator itself. I mean, you know, once you get over that weird yield keyword, it's fairly straightforward. 

CHARLES MAX_WOOD: Yeah. Well, it's it. You're right in that sense. But again, you know, and this is back to what AJ was saying before when we were talking about iterators for a minute. And some of the stuff there with symbol dot iterator. And this is something where if you know that this is a generator and you know that that's how this works and you've done it enough to where you kind of have internalized it, then it's not weird. But otherwise, it looks like something that it is not. And so it makes it you're going to have to stop and kind of squint at it for a minute, especially if you run the code and you're not getting back what you think you're going to get back 

DAN_SHAPPIR: either do a gen space function like they did with the async function or just drop the function keyword altogether and just use the generator keyword or something like that. 

CHARLES MAX_WOOD: Yeah, yeah, yeah, yeah. I'm with you there. 

DAN_SHAPPIR: But this is what they did. So it's function asterisks or function star, call it whatever. Now here's the other interesting thing. Like I said, you run until yield and the value provided via yield is then returned from the iterator. But the function, the generator, is kind of stuck at that point. It didn't complete. It's not done. Because when you call next again, it resumes right after that yield and continues to run until the next year. So that sequence of code runs until it blocks then resumes and continues to run until it blocks. And what does that sound to you like? Sounds exactly like a sink away. And in fact, I think that in terms of the JavaScript engines, they, when they created this whole generator mechanism with the yield, they were kind of thinking like, we're going to have to do all this stuff for a sink away anyway. So we might as well create generators, run code until a particular point and then block there and then resume running from that point in code and at some future time. Something that was previously totally not possible in JavaScript. AJ, you look pained. 

AJ_O’NEAL: I am. I had my terminal open and I was just testing some stuff out and not my terminal, my Chrome console tab. 

 

Have you ever wondered if you could be offering a faster, less buggy experience for your customers? I mean, let's face it, the only way you're gonna know that is by actually running it on production. So go figure it out, right? You run it on production, but you need something plugged in so that you can find out where those issues are, where it's slowing down, where it's having bugs. You just, you need something like that there. And Ray Gun is awesome at this. They just added the performance monitoring, which is really slick, and it works like a breeze. I just, I love it, I love it. It's like, it's like you get the ray gun and you zap the bugs. It's anyway, definitely go check it out. It's going to save you a ton of time, a ton of money, a ton of sanity. I mean, let's face it, grephing through logs is no fun and having people not able to tell you that it's too slow because they got sidetracked into Twitter is also not fun. So go check out ray gun. They are definitely going to help you out. There are thousands of customer centric customer focused software companies who use Raygun every day to deliver great experiences for their customers. And if you go to Raygun and use our link, you can get a 14 day free trial. So you can go check that out at JavaScriptJabber.com slash raygun. 

 

AJ_O’NEAL: Okay, so I don't know. I mean, I don't think that you can redeem this for me to convince me that this is good. 

CHARLES MAX_WOOD: I love it. 

AJ_O’NEAL: Like, cause there's some things, there's some things where I've said, okay, if this was a different language, if it weren't JavaScript, a language that has these features, this is a cool feature to have in a language. I look at this. This does not appear to me to be a feature that's cool to have in a language. This looks like some people that are really interested in functional programming and math and symbols got together and were like, wouldn't it be cool if we had yet one more way to do this thing that we already have several ways to do? And so I I have seen this once or twice. Like there was some, some frameworks that came after express. I think Koa was one, and I feel like there was another one that they were based on like a generator pattern or a promise pattern or something like that. I think the generator pattern came first. And I think I'd seen this around then, but I, I don't, I don't know if I've seen anybody use code like this. And honestly, to me, it's a lot easier. I would think to just explain to somebody, okay, symbol dot iterator is a new type of primitive in the way that a string is a primitive and a number is a primitive, a symbol is a primitive, and the symbol.iterator primitive is the value of itself. So the same way that the value of the string iterator is iterator, the value of symbol.iterator is symbol.iterator. That's a little confusing, but if you can get beyond that, the key is allowed to be a string or it's allowed to be a symbol. And symbol dot iterator is a valid key. I don't think I explained that as simply as I could. If I sat down and thought about it, I could maybe eke out an explanation that like in one minute, someone could understand what a symbol is, but with this. I just feel like this is the bridge too far. It's so much easier to say, here's how to use symbol dot iterator than it is to say, well, here's how to use function star with yield, especially in the world where no one uses functions anymore. I mean, like I classify ECMAScript as an entirely different language. None of the syntax is the same. You need an entirely different parser. None of the bits of the original JavaScript parser other than A equals two, you know, the variable assignment, none of the rest of it is even the same parser. So it's a completely different language. So let's give it that. This right here, now I can't use the ECMAScript syntax. I have to use a Quasimodo version of the ECMAScript 5 or what I call vanilla JavaScript syntax. So now you're in no man's land because it's not vanilla JavaScript and it's not ECMAScript. 

DAN_SHAPPIR: Let me put it differently then. If I understand you correctly, if the ECMAScript people had implemented iterators and maybe even instead of symbol.iterator just specified that it's supposed to be a method called iterator, something like that. And like you have a next, which is just a name, they could have specified it instead of writing symbol.iterator, it just be called the string iterator, whatever. If they had done that and implemented iterators over collection, and you would have to write them the long way, quote unquote, or the explicit way, and they never created generators, you would have been fine with it. 

AJ_O’NEAL: Yeah, and your library example, I think, is absolutely perfect. Having a collection of functions that can work that work over collection and specifying into a standard. We have a way that all collections should work in JavaScript. That is perfect. That wouldn't have required to change the language. Earlier, you said that iterators don't require a change to the language. They do. They required you to have symbols. So without symbols, you couldn't have iterators in the way that they've implemented, but in a normal everyday implementation of this, there's no need for symbols either. So there's no need for any change to the syntax, like all of the change to the syntax would be completely optional. If you want it to be sugar-coated and you wanna use the ECMAScript style syntax, you can. If you wanna use vanilla JavaScript, you can. The only thing that's different between the way that you've described an iterator and what you can do in vanilla JavaScript is using a symbol as the name. Other than that, it's vanilla JavaScript. And your collections pattern is basically just like Lodash. You know, you're just saying, here's a collection of functions pass in an iterable object into the function. And then instead of doing like Lodash does, where there's like a bunch of these little one line utilities that you have to go through 10 of them to figure out what is actually being done and how it's iterating over the object, you would have a standard way of knowing this is how it iterates over an object if that object has iterate function and an X function. 

DAN_SHAPPIR: And this is essentially what was done in C++, by the way, when iterators were added into C++. The language itself was not extended in any way in order to support the iterators. They just created an agreed upon interface, let's call it, that everybody used. So they didn't extend the language. And I tend to agree with you there. I think that the, I don't know if, I'm less extreme about extending the language than you are. I'm actually, and I'll explain in a minute why, but I definitely agree that they could have avoided this whole generator thing, just gone with the iterators. It would probably have been good enough and maybe they would have gotten greater buy-in into this feature if they had. And it certainly doesn't fix the big missed opportunity, which is the lack of a standard set of functions which actually use iterator. 

AJ_O’NEAL: I mean, I brought this up in the last episode, but aside from the concern about infinite memory consumption, there is no, and we see this already exists with Lodash. Okay. So it already exists. You can have a set of collection operators. I'm not using that term correctly, but you can have, you know, a sort, a map and each a filter reduce like all of these things that we want to be able to do on collections. You can have a, you know, skip every other, I mean, whatever you want. All of those you can have with arrays and objects. The case where they fail is where you're dealing with an unbounded set. To me, that is where an iterator can provide a nice liaison, if you will, between the two paradigms, is that an iterator can work for a data set that's one terabyte in size. An array cannot work for a database that's one terabyte in size. That said, I mean, other than Node, and there is Papa parse. Papa parse, but then there's other problems, being single threaded and having to use web workers and stuff like that. I just think the use case where JavaScript has unbounded sets is a very slim use case. Doesn't mean that we shouldn't support it, but there are very few use cases in JavaScript where you have unbounded sets and you don't have to use some other convoluted feature to overcome whatever the limitation is. Papa parse works with unbounded sets. For those who don't know, you can parse gigabytes of CSVs with Papa parse, but in order to do it, you have to use web workers and it has to have a cross communication channel because you can't realistically do anything in a single thread in JavaScript when you're dealing with gigabytes, because you have to pause and let the event loop catch up every so often. 

DAN_SHAPPIR: And if I can interrupt, this is exactly where the benefit of asynchronous iterators shines in because now you can, you don't just iterate in space. You can iterate in time. So while I can't have a huge number of items simultaneously in memory, I can get them spread over time. That's perfectly acceptable. And everything is asynchronous. 

AJ_O’NEAL: Yes. And 

CHARLES MAX_WOOD: I can batch them in or. Yeah. Wait for memory to clear or whatever. 

DAN_SHAPPIR: Right. Exactly. 

AJ_O’NEAL: It depends. I think you'd have to use a mix of the two. Like for example, I've used web crypto and web crypto is so incredibly poorly implemented that it's literally unusable. Like you have to go back to vanilla JS libraries for, for all, but the most simple tasks that are done one at a time because it's async, which is good. But there's the overhead of the context switching and the event loop between every single async call. So if you want to do an operation that's only slightly CPU intensive, like generating a SHA-256 hash, and you put that in something that's async, all of the additional overhead that goes into the async means that instead of being able to do 100,000 hashes in a second, you can do a couple hundred hashes in a second. And those numbers are probably off. I don't remember what it was in testing. It probably wasn't that big of a, no, it was that big of a difference. It was huge. It was on the order of like seven, more than one order of magnitude difference. So with the, like, and that's why Popa parse uses web workers because you need it to be continuous. You can't do async things and have it be performance if you need to be able to batch them. Like you can do a hundred of them or a thousand of them or 10,000 of them at a time and it'd be performant if you do that and then switch and then do another batch and then switch depending on the processing load. But you cannot have async functions be performant if you need to do many operations and the load size is negligible compared to the overhead of the async mechanisms. 

DAN_SHAPPIR: Look, JavaScript is a high level programming language and the architects of JavaScript from the get-go sacrificed performance for, let's call it ease of use, readability, simplistically call it whatever. You know, if you want to implement something that's, that provides really amazing throughput in a browser or a node you these days, you know, you should probably use, I don't know, maybe Rust and WebAssembly or something like that. JavaScript creates objects 

AJ_O’NEAL: around and JavaScript has been more performant than anything else almost ever. I mean, JavaScript is incredibly performant in the way that it's implemented with JIT. 

DAN_SHAPPIR: I agree. The creators of JavaScript, the JavaScript engines... 

CHARLES MAX_WOOD: I'm going to cut you guys off in like two minutes. Then I will... I'm going to get the picks. 

DAN_SHAPPIR: Yeah. So I'll just finish this sentence. I'll say this. The creators of the JavaScript engines have done an amazing work. But even then JavaScript is not C++ and it isn't Rust. And there are some intrinsic overheads associated with using JavaScript, like the fact that it creates objects all over the place for everything. And even though it does it really efficiently, there's still associated overhead. And like you said, if you're doing a lot of context switches that has a price. Before we finish and go to picks, I'll just add the last bit of information, which is we had generators for creating iterators. You also have async generators for creating async iterators. So all you really do is put the async keyword in front of the function star. And then when you yield, it actually creates a promise and yields a promise. And, and now you can, because it's asynchronous, you can also actually use a weight within the generator. So you can await for something, get it, and then yield it. And this way you can implement asynchronous patterns in a fairly straightforward way. And again, I think that's actually where generators start to shine, because if you want to use generators with a sink or weight, doing it with raw implementation of iterators can actually get fairly hairy. And like I also said before, I think that the people that introduced yield into JavaScript made the assumption that we're going to be introducing a sync await anyway, so we're going to have to implement a mechanism for pausing and resuming execution of blocks of JavaScript code. So it's not as if we're just introducing this for yield where it might not have been worth it because of a sync await. It's actually something that we're going to be doing anyway. So let's also get yield along for the ride. And with that, I think I more or less covered the topic.

CHARLES MAX_WOOD: All right, good deal. Go ahead, AJ. 

AJ_O’NEAL: I'm going to compare this to Apple's M1 versus Intel processors. The more crap that you add into something, the more you have to deal with it sooner or later. And the reason that I really do believe that M1 is a game changer for the industry. And the reason for that is they said instead of how can we do more and cram more crap into a single processor, they said, how can we do the least amount possible to get by and then create other small functional units that can do the least amount to get by. And now you've got a processor that is three times faster than any of the other leading processors at, was it like one, somewhere between one quarter and one tenth of the power consumption. 

DAN_SHAPPIR: It also helps that they can cram four times as many transistors into the same silicon space. 

CHARLES MAX_WOOD: So that is also that. 

AJ_O’NEAL: Sure. But well, but if you did that with Intel then you would just end up with something that's four times hotter. 

DAN_SHAPPIR: So I think that was part of the problem by the way. 

AJ_O’NEAL: Well, yeah, but that's, that's what I'm saying. Like the JavaScript parser is actually getting slower. I I'll stop. I'll stop. I'll stop. 

CHARLES MAX_WOOD: Well, maybe we should just have an open debate episode at one of these points and yeah, we can have this debate because I kind of see both sides of it, but I don't think we have time to treat it here. 

 

Do you want to increase your level of contribution to your company or team, move into an architect or expert role? Do you want people at work to see you as that go-to person for technical knowledge? Well, let me help. I'm starting a program to help developers move up in their careers using proven techniques and by starting a podcast in order to advance. Right now I'm only scheduling calls to see where you're at, where you want to go and how we can get you there. There's no sales pitch involved. You can schedule a call with me at devchat.tv slash next level. 

 

CHARLES MAX_WOOD: Um, let's go ahead and do some picks. AJ, do you want to start us off with the picks?

AJ_O’NEAL: Well, yeah. So first of all, I want to pick our lovely Chuck because man, it's been so long since we've had you and it is a pleasure to have you back. I love you. You know, just, 

CHARLES MAX_WOOD: I love you too. 

AJ_O’NEAL: Yeah. Yeah. That, but I was going to say, um, that was going to be a complete sentence, the way that you're framing questions and things, you know, for the audience and whatnot, and maybe for yourself as well. But I think, you know, a lot of it's you're, you're trying to get us to speak. 

CHARLES MAX_WOOD: It's a little bit of both.

AJ_O’NEAL: So I really appreciate and want to thank you for that. I'm also going to pick a couple of things. Let's see. The first one is going to be Jordan Peterson's 12 rules for life. I just talked about that while we were chatting before the, the, the show, you know, it's basically the alt right playbook, how to hate everybody. Oh wait, no, that's not it at all. So there's, there's a lot of criticism about it because some people don't like Jordan Peterson because they don't just like him as a person, but his book is actually pretty good and it's very simple. I mean, I don't think these are things that you can really disagree with at a fundamental human level. I think it's pretty hard to make a case against them. One of the ones that I like the best in the book meanders. So if you're not okay with a book that doesn't get straight to the point, it's not for you, get the poster instead. And I'll link that as well. But the most 

CHARLES MAX_WOOD: there's a poster. 

AJ_O’NEAL: Yeah, I got it. My wife actually got it for me for Christmas. I mean, like just individual people make posters and some of them have maybe gotten copyright strikes on Amazon or whatever because I'm I typed in 12 rules poster and I'm not seeing it come back up because he probably wants to reserve the right for making that poster. Yeah, it looks like they got rid of them but I got one before they got rid of them and the most interesting one is don't bother kids while they're skateboarding and the explanation that he gave for this was just phenomenal in the sense It was so in-depth on so many levels. So I'll just tackle like one or two of them. But basically he said if you we we actually want children to to do their own thing even when it's potentially wrong or dangerous because it gives them learning experience as long as it's when in certain bounds of reason. We want them to be able to experience, you know the thrill of being brave and most importantly mastery because skateboarding is something that it's not easy to master It's not easy, but anybody can do it, you know, like riding a bike or whatever. And in the olden days, I guess, BMX bike riding was maybe the thing before skateboarding or after skateboarding or whatever anyway, but that was, that was a point. And another one is, you know, he talked about how the methods that people use to prevent kids from skateboarding, like putting studs in the sidewalk, putting studs on railings. He gave an extreme case, but he just talked about how the things that you do to prevent, prevent behavior that because of your own bias, you don't like, because there's not like an objective reason why skateboarding is bad. It's just some people don't like it or they feel like it's a ruffian thing to do, but you could say that about a lot of things in life. And he talks about a case of one park where they basically ruined the park and then family stopped going there because they put up fences in weird places and they put studs in the sidewalk and they put studs in the railings. So then it wasn't safe for kids and like old people were tripping. And then after all this, the park basically became abandoned and became a place where homeless people hung out. And it's like it went because they did, they went so all in on making sure that it was not possible or pleasurable to skateboard on any surface in the park. They just ruined it. And so anyway, I thought that was pretty cool. And not that that was pretty cool, but his way of like connecting and explaining why it's important for us to be accepting of people doing things that maybe we don't understand and whatnot. And then the other thing that I was going to pick today, I'll keep it short. I meant to pick this last week is the Brave browser. I don't think I actually did pick it last week, but I've started using the Brave browser and we had, oh gosh, Samson. That was, I think that Samson or Samson. Anyway, we had one of the guys from the Brave team on the show a while back and I wasn't convinced as you know, normally I'm not. But I ran into a case where I just started to feel a little uncomfortable about the way that my searches were potentially being related or I don't know. It just, just something kind of seemed a little off or a little weird to me. And I was like, well, I'll give Brave a shot because I'm kind of at the point where some of those stuff's getting a little too weird even for me. And it's been working pretty well. There's a couple of niche use cases related to third party cookies and an iframe and some stuff like that that it doesn't allow, I haven't hit it on any of the sites that I've used, but I did hit it on a site that I was trying to develop because I was doing a, trying to make a seamless login system. And I needed to use a cookie and an iframe to convey some user session information. 

DAN_SHAPPIR: Tracking cookie. 

AJ_O’NEAL: I mean, I guess so, but I mean, that's what logins are log into a site because you want it to remember who you are from one page visit to the next and in one tab in the next etc. 

DAN_SHAPPIR: So yeah that's why we can't have nice things on the on the internet because you know people do nasty things with with things that would have been extremely useful and usable otherwise. 

AJ_O’NEAL: Yeah yeah I'm not going to go into that but um the other thing that I was going But Need for Speed, Hot Pursuit on the Nintendo Switch is amazing game, which means that on the PlayStation and the other systems, it's even a more amazing game because the Nintendo Switch is terrible in terms of performance and frame rates and all those things that most people care about. And it uses Xbox style controls. So instead of the normal Nintendo way of the A button being go and the B button being break, it is the R trigger is go and the left or the L trigger is break. And then A is Nitro. So it was a different style of control, but it feels nicer for a more serious game, like, well, I don't know if you feel serious, but you know, compared to Mario Kart, which is a goofy, fun, silly game need for speed, having that control of the L and R I find it to be. I don't know. It's, it's very nice for the style of game that it is. I've, I've been converted over to the Xbox way of racing games through this. 

DAN_SHAPPIR: So So you're getting an Xbox or a PS5? 

AJ_O’NEAL: No, no, no. I'm sticking with the Nintendo. Don't get me wrong. I'm not leaving Nintendo because they're literally the number of games that aren't made by Nintendo that I play. I can count on one hand, unless you want to count the games that are endorsed by Nintendo that aren't made by Nintendo, like Hyrule Warriors, which is kind of meh. But you know, then maybe I'd have to use two hands because I do have a number of official Nintendo titles not developed by Nintendo. Anyway, that I'll leave that That's my stuff for the week. I probably had some more JavaScript-y, actual technical pick, but snapdrop.net. Try that out again. That's all. 

CHARLES MAX_WOOD: Awesome. Dan, what are your picks? 

DAN_SHAPPIR: Okay, so I have a few. First of all, I picked it before, but it was so great. It's so great. I have to pick it again. The Queen's Gambit. If you haven't watched it, then do. It's just an excellent series. It's the script is great, the acting is great, the directing is great. It's a limited series, which means it's just these episodes and it's over. And that's also part of its appeal because it's a whole and complete story. And there's no need to, to go beyond, beyond the story. If you haven't watched it, I highly recommend it. So that's 

CHARLES MAX_WOOD: on Netflix, right? 

DAN_SHAPPIR: Yes, exactly. By the way, I have to say something. I'm, you know, we also have Apple TV or whatever they call it because we bought some Apple thing and they do have some good content, but the interface is funky. I mean, you would think that Netflix interface isn't, you know, that sophisticated, but you know, it takes you want some interface that's not as good to show you how well crafted the Netflix interface is. I don't know. We, we stop start shows and My wife likes to get the Hebrew subtitles because she's not as fluent in English as I am and sometimes it works and sometimes it doesn't And and it's much more likely to stutter than Netflix is and the list just goes on and on so that they have some excellent content But the implementation is just not as good. 

AJ_O’NEAL: The Disney app is terrible. Can't get Mandalorian to sync to my phone 

CHARLES MAX_WOOD: Oh Disney Plus. 

DAN_SHAPPIR: Yeah Yeah, it's also getting really problematic with all these services. I mean, how many services am I supposed to get? 

AJ_O’NEAL: I think as many as you would have gotten if you were paying for cables. So put $70 at the cap and just subscribe to them up to that. And that's your TV bill. 

CHARLES MAX_WOOD: Honestly, we're saving money off of what we used to pay for Dish Network. And we're paying for like, yes, EBS and Disney Plus and a couple of others. 

DAN_SHAPPIR: Look, we had like...BitTorrent and stuff like that for a while because people just, you know, couldn't get the content that they wanted. It was too expensive. And then Netflix came along and suddenly it was totally reasonable to get all the content that you wanted it. Now it's becoming extremely expensive again. So I'm guessing a resurgence in BitTorrent use. 

AJ_O’NEAL: Yeah. I don't know anything about that. I mean, I certainly can't watch anything that I want on my phone by syncing it through the VLC app. I would know nothing about that. 

CHARLES MAX_WOOD: Exactly. I've never ever used BitTorrent either, not me. That would be horrible. 

DAN_SHAPPIR: Anyway. Oh yeah. And my final pick, this just came along more or less as we were doing the show. So I literally have no idea how good this is, but it looks really interesting. It's something called AutoWebPerf. It's some thing, tool, service, whatever created by Google that let me just read it out. Webperf is a modular tool that enables automatic gathering of performance data from multiple sources. Basically, it's some sort of performance data aggregator that can work with the Chrome UX report, with Lighthouse, with web page test, and collect all this data, and then somehow aggregate it so that you can view it and play with it. Sounds seems interesting, seems useful. Hopefully it actually is. So I posted a link to that as well. And I'll certainly play with it. 

CHARLES MAX_WOOD: Yeah. It sounds like something worth playing with for sure. 

DAN_SHAPPIR: And those are my picks for today. 

CHARLES MAX_WOOD: Good deal. I'm going to throw out a few picks. Um, I know that this comes out in like a month or so, but by then we should be well underway with a lot of this stuff. So over the last few weeks, I'm just going to kind of explain a little bit of what I've kind of been working with and going through. And I kind of went through a period of not really knowing what I wanted to do or what kind of contributions I wanted to make out there to the world. And then I realized that I really do love helping developers, but I want to help developers level up. I want, and not just level up in sort of the, Hey, get better, blah, blah, blah. Right. But specifically, we don't just do development just to write code, right? We're not in this just for the sake of writing code. I mean, it's, it's definitely awesome that something that I love to do is something that I can get paid to do, if that makes sense. But at the end of the day, I have all of these other things that I want to do with my life. And so my programming career is just something that will facilitate some of that and is also something that I can invest in along the way for other types of fulfillment, right? So the number of people that were able to help with the podcast, right? adds to my fulfillment, but also hanging out with my kids and doing things with them, right we're launching, I'm launching four more shows. And it's because I'm watching one with my 15 year old, one with my 13 year old, one with my 11 year old and one with my nine year old. Right. And we're not talking about code. We're talking about other stuff. In fact, my 15 year old, we're doing a YouTube channel and we're just going to be playing video games. Right. So he, he talks incessantly about a game called undertale. And so we are going to be playing undertale on YouTube every week. Right. I'm sorry. That's not your thing. Yeah. Oh, he plays that music all the time to address my wife insane. 

DAN_SHAPPIR: But anyway, so what are those YouTube gamers that has a trillion followers and makes a ton load of cash from just playing games? 

CHARLES MAX_WOOD: He will be. It's his channel and I'm going to be teaching them. Yeah, essentially. Okay. You know, here's how we build a channel. Here's how we monetize a channel. Here's how right. And so I'm going to be working through that with them. But a few things that I'm going to put out there just so people know how I plan to help you all. Sorry for the tangent is I'm really going to be focused on and I'm going to be reviving the show called the dev rev, which I kind of halfway started, but I didn't really know what I wanted it to be. It's going to be focused on helping people become the top 5% of developers in the field that contribute to the community, contribute code that contribute to their teams and do that in a meaningful way, but also that build careers that support the other aspects of lifestyle that you want. Right. And I don't know if that's traveling the world. I don't know if that's being a beach bum when you're not at work. I don't care, right? But ultimately it's okay. How do you make the kind of money and the kind of impact that are going to fulfill you? And I'm refocusing a lot of the shows too, so that we can make sure we're covering topics to help you with that, right? So JavaScript Jabber, we're going to make sure, and I feel like this episode was kind of right in that vein, right? It's something that you understand that's going to get you ahead. It's going to move you up the ladder that, you know, even if you don't ever write your own iterator, you're not. You kind of understand how they work now. Right. And so when your team runs into some funky snag, you can go, okay, let me go look at this and you know what you're looking at when you look at the iterator, right. And I'm kind of in that same position at my full-time job where I'm sort of the resident rails expert because I've been doing it for 15 years and right. So they asked me a question and half the time, I don't even have to think I can just tell them what the answer is. And it's not because I'm so smart. It's because I have put in the time and the effort to learn it. And so I'm working to accelerate people in that way. So I really have plans to build this out into a collection of things that will help you do that both in JavaScript and the technical skills, but also in your career skills and things like that. And I'm also planning on putting together some stuff for manage, you know, if you want to do the management track, if you want to do the influencer track where you're doing a podcast or YouTube or screencasts or whatever, right. But help people make that or being a speaker conferences because I feel like a lot of people don't understand that they can do that. And I really want to open up those opportunities to, and help you go from kind of the 5% developers that are the key people wherever you're at to the 1% people who are the key people in the community. And I feel like if we do that, we can have a really, really positive influence on the community. And so it sounds really ambitious and it feels really ambitious, but that's what I want to create. And so, to get things started, I am working on some other avenues that are in the podcast space. And one thing you all can do to help support the shows, because we had a monetization slowdown for about, what, like 8, 9, 10 months. It's starting to come back. But I still need to support the network for a couple of months before that really kicks in. I found a company that will help me find sponsors, but they pay two months after the sponsorship's run. So I have basically a two month gap I've got to figure out. So what we're going to do is we're going to put together a JavaScript jabber premium. And all that is, is you sign up and then you get the episodes without the sponsorship messages. And then I may talk to the hosts and see if we want to add other stuff to that. But for right now, that's what it is. It'll be five bucks a month. And mostly it's, it's just kind of a, Hey, thank you for people who want to support the show, but keep an eye out because I am going to be putting together other things. I'm working on putting together a discourse forum for JavaScript folks. You can, we can discuss all this stuff and I'm planning on putting extra content in there. Honestly, seriously looking at actually doing some form of a, an exclusive podcast just for people in the forum, right? So we'll just drop it into the forum and if you want to play it, you have to sign into the forum and press play, right? But then we can have a conversation about whatever the topic is and it'll be a real short episode, but that'll help you level up on a regular basis, right people that kind of get to the higher levels of contribution doing that a lot of people don't think they can do or aren't willing to do. And so I'm going to be talking a lot about that and I'll be doing that on the dev rev, but yeah, I'm really fired up about this. I'm super excited to get it together. And so, um, essentially what I'm, I guess I'm picking is the dev rev. Um, there's some stuff at most valuable.dev that I'm also going to be putting out there and yeah, we're, we're just going to knock it out of the park. But if you want to be leveling up, whether you're a junior person and trying to kind of get to that higher level of contribution on your team or you're a senior person who's kind of at the top of your game and you're like, okay, where do I go from here? And so we can start talking about management or influencer, or I had another track that I was also looking at, but I can't remember. But yeah, so we'll work through that and we'll get all the people involved so we can get you there. And then from there, you know, then we can talk about how this plays into other aspects of, you know, kind of where your life journey goes from there. So, that's, that's a lot of the focus. So yeah, so the, the big, the big one is the dev rev.com and then most valuable.dev. And then, um, I'm also just going to shout out cause people might be interested in gear. So for the YouTube channel, I have a cam link 4k that I got mostly to make courses with, but it turns out that you, uh, it takes an HDMI input so you can plug a Nintendo switch into it. And that's how we're streaming the Nintendo stuff to the YouTube and then it actually goes into the computer and then we've also got just the microphone hooked up to the computer. And so we're just going to talk our way through playing Undertale. And so I've got all my audio equipment in here as well. But boy, I've never seen a 15 year old so excited to do anything in my whole life. So anyway, that's kind of what I'm working through. I'm also documenting all the processes for all the podcast stuff, podcast playbooks. You can go check that out at podcastplaybook.co and Yeah, that I just I kind of wanted to put that vision out there I'm probably going to actually put up a youtube video and talk for half hour and just walk you through where i'm going to take this but don't be surprised if you see us start turning out a bunch more content and doing some things that you really haven't seen come out of devchat.tv 

DAN_SHAPPIR: I just wanted to add that if you can get your 15 year old son to be excited about doing some joint activity with you. Beyond anything else, that's already worth it. 

CHARLES MAX_WOOD: Well, it's funny because you mentioned that and like I sat down with my nine-year-old and we recorded the first episode of his Star Wars podcast, right? And what's funny is, we're talking about a movie, right? You know, or they've got cartoons, they've got Mandalorian. I think we're going to actually go and talk about Mandalorian more heavily. But anyway, what's interesting is we sit down and we start talking about it. And I don't know, I'm going to throw another pick out. It's the, the hero with a thousand faces. It's a book by Joseph Campbell. It's about a 60 year old book. And he talks about this concept called the hero's journey that these heroes go through. And it's, it's basically a journey of three acts. My so like Dante's divine comedy is a journey in three acts, right? You've got all of these others all the way through history, you know, both ways. They use it in movies all the time. It's kind of spoiled movies for me because I sit down and then I'm going, I bet this comes right about now. And sure enough, there it is. So anyway, but, but what's great is I can sit down and I can talk to them. Okay. They hit this challenge and now they're dealing with this thing and now they're having this kind of growth. And then we relate it back to real life. And I get to have real life conversations with my kids because star wars, which is really cool. So anyway, those are my picks. I know I was kind of all over the place. Keep an eye out for that video as well, I guess I'll put it on the dev rev probably as episode one, even though those episodes are probably going to be like 15 minutes, not 30 or 45 minutes. But yeah, that that's where we're going with this. I'm going to be working out my full vision on this on my whiteboard, probably this afternoon or tomorrow. But I, I've got some really big plans and I don't see any reason why this can't just be a major force for good within the tech community. And that's, that's kind of where I'd like to take it. So anyway, 

DAN_SHAPPIR: Sounds good. 

AJ_O’NEAL: One note on that Chuck, cause you mentioned the cam link. I have to mention the Flint 4k P because it's way easier to use and rock solid reliable and not so pricey. 

CHARLES MAX_WOOD: Okay. Fair enough. We'll put links to both in there and then people can go look and see which one they think they want. But I don't know about anything about that one. I just know that the cam link works for me. 

AJ_O’NEAL: So I'm going to ask you one question about, do you have to still install the drivers with it or is the new version like you can just plug it in and it works?

CHARLES MAX_WOOD: I think I had to install drivers for it. I'm on a Mac. I don't remember. I've had it for a couple of years. 

AJ_O’NEAL: Oh, okay. Okay. Well then, all right. But anyway, all of that sounds really good. Sorry to jump in with that technical note. It's just, it's just, 

CHARLES MAX_WOOD: I know it's all good. 

AJ_O’NEAL: Those were so expensive, especially during the pandemic, like the price of those skyrocketed. And there's this, like I bought literally four of these things and tried each one and then found that this one was the best bang for buck. Like a lot of the cheap ones, like you plug them in half the time, they work. You got to unplug it, plug it back in, unplug it, plug it back in. The audio doesn't work on plug it, plug it back in. I didn't try that that one because it was like $400 or something amazingly ridiculous at the time. But this is great. 

DAN_SHAPPIR: You're such a techie. 

CHARLES MAX_WOOD: Yeah. Well, I mean, if it's easier and cheaper, yeah, go get that one for sure. All right. Well, I'm going to go ahead and wrap this up. Thanks guys. This was really terrific. 

DAN_SHAPPIR: Yeah. 

AJ_O’NEAL: Probably the longest picks we've ever had too.

DAN_SHAPPIR: Yeah. And I think we also had the first time at least since I've been on the show where we actually have real code in the show notes. So we'll see how that goes. Yeah, it's gonna be epic. 

CHARLES MAX_WOOD: Yeah. Alright, folks, Max out. 

DAN_SHAPPIR: Bye. 

 

Bandwidth for this segment is provided by Cashfly, the world's fastest CDN. Deliver your content fast with Cashfly. Visit c-a-c-h-e-f-l-y.com to learn more.

 

Album Art
JSJ 469: The Case for JavaScript Iterators and Generators, part 2
0:00
1:18:24
Playback Speed: