JOE:
We’re developers. We use, Wii Us!!!!
[This episode is sponsored by Frontend Masters. They have a terrific lineup of live courses you can attend either online or in person. They also have a terrific backlog of courses you can watch including JavaScript the Good Parts, Build Web Applications with Node.js, AngularJS In-Depth, and Advanced JavaScript. You can go check them out at FrontEndMasters.com.]
[This episode is sponsored by Codeship.io. Don’t you wish you could simply deploy your code every time your tests pass? Wouldn’t it be nice if it were tied into a nice continuous integration system? That’s Codeship. They run your code. If all your tests pass, they deploy your code automatically. For fuss-free continuous deliver, check them out at Codeship.io, continuous delivery made simple.]
[This episode is sponsored by WatchMeCode. Have you been looking for regular high-quality video screencasts on building JavaScript done by someone who really understands JavaScript? Derick Bailey’s videos cover many of the topics we talk about on JavaScript Jabber and are up on the latest tools and tricks you need to write great JavaScript. He also covers language fundamentals, so there’s plenty for everybody. Looking over the catalogue, I got really excited and I can’t wait to watch them all. Go check them out at JavaScriptJabber.com/WatchMeCode.]
[This episode is sponsored by Component One, makers of Wijmo. If you need stunning UI elements or awesome graphs and charts, then go to Wijmo.com and check them out.]
CHUCK:
Hey everybody and welcome to episode 117 of the JavaScript Jabber Show. This week on our panel, we have AJ O’Neal.
AJ:
Woo hoo!
JAMISON:
Hello friends.
CHUCK:
Aaron Frost.
AARON:
Hello.
CHUCK:
Joe Eames.
JOE:
[makes sound effects]
CHUCK:
I’m Charles Max Wood from DevChat.TV. And this week we have two guests. We have Gerred
Dillon.
GERRED:
Hello.
CHUCK:
And Will, is it Conant?
WILL:
Conant.
CHUCK:
Conant.
WILL:
How are you doing?
CHUCK:
Do you guys want to introduce yourselves?
GERRED:
Sure, yeah. My name is Gerred Dillon. I’m a developer evangelist for the Ionic framework, an AngularJS mobile framework, and an indie game developer.
WILL:
My name is Will Conant. I’m a web developer working at [inaudible]. We do e-commerce, affiliate marketing, stuff like that. And we’ve been working with Node.js almost exclusively for the last three years.
CHUCK:
Awesome. Do you want to explain a little bit? We’re going to be talking about Koa. Do you want to explain a little bit about how you got into Koa? One of you does a mobile framework and…
JOE:
Hey, before you ask that question, I got one question for Will. Is it purely coincidental that your last name is really close to Conan?
WILL:
I don’t think that it’s entirely coincidental. I think the names are in fact related in some obscure way.
JOE:
Are you like a barbarian developer?
WILL:
I do not have a barbarian developer physique, unfortunately. I’ve tried, but just a skinny dude.
AJ:
Ooh. Sorry. [Laughter]
AJ:
I was looking at the Koa documentation.
CHUCK:
Uhuh, yeah.
AJ:
At a completely inappropriate time.
WILL:
Skinny dude, ooh.
CHUCK:
We’re not that kind of show.
JOE:
Yeah. And moving right along.
AJ:
I’ll mute myself while reading documentation so I don’t get too excited and…
CHUCK:
Oh man, yeah, documentation.
AARON:
Yeah, don’t say anything else.
CHUCK:
[Laughs] So, I’m kind of curious. How did you guys get into Koa from something like Ionic or the other stuff that you guys do?
GERRED:
When I actually started messing around with JavaScript generators and Koa, I was actually working on another project at the time and onboard with Ionic. And so, I have a deep interest in distributed systems and server development, especially with game server development. And so, as soon as I discovered co, which is the flow control library that Koa is based around, I got really into doing that sort of flow control. I started working on building out my own web framework with that and ended up discovering Koa, read through the source, fell in love, and didn’t really look back.
WILL:
For me, I actually have been following the development of something like Fibers or coroutines in JavaScript for a long time. [Inaudible] was very, very early adopters of Node. And when we started we felt like it was going to be pretty difficult to handle the callback situation. So, we’ve gone through a lot of different approaches to this. We first used CPS transforms, things like TameJS or StratifiedJS. And then after a while, we actually started using a module called Fibers which introduced full coroutines into the V8 engine. But those sorts of things were unwieldy and it’s hard to get a lot of community support behind them.
And so, we’ve been eagerly awaiting the arrival of generators in JavaScript, because they’re actually part of the language. It’s not a hack to have generators. And they give us a lot of the same power as those things, those things like Fibers did. And so, when I saw TJ Holowaychuk’s Co module, like Gerred, the same thing, I was really excited about it and started playing with it and actually made a few minor contributions to it right at the beginning. And then the Koa framework really, really impressed me. And we’ve been doing some things internally with that.
CHUCK:
Can you explain really quickly what generators are?
GERRED:
So, generators is basically a, I would call, Will you can correct me on this, coroutines lite in JavaScript. So, it gives you a base level of the ability to yield the flow of execution within the V8 engine. And from there basically get an object back that you can start to interact with and resume control when it’s allowed to. So, it really enables very synchronous-looking code, much like Fibers would or any other sort of coroutines, but within JavaScript. So, it’s a way to get away from that nested callback nightmare that so often plagues JavaScript. And we’ve worked to, for a long time, really to come up with solutions for.
WILL:
Yeah, and one the interesting things about the generator construct is that it is not inherently designed for asynchronous code, for managing asynchronous complexity. It just lends itself to asynchronous complexity really well. So, you have to end up using something like generators combined with something like promises to get the effect that you see in frameworks like Koa.
JOE:
So, if you’re using a language, there are a lot of languages out there that actually have a yield statement that functions very similarly to how generators function in JavaScript. So, that was the whole intent behind them, was basically to be able to produce collections, an object that generated things, but you could generate them at runtime or at the last possible moment. For example, like Fibonacci sequences right? You wouldn’t want to create a collection of all the numbers in the Fibonacci sequence, or prime numbers. But when they ask for the next one, it’s easy to go and generate the next one.
So, that’s what generators were. I know that I worked in C#. C# had this same kind of construct. It was a lot more limited than the way that JavaScript generators are going to work. But yeah, I think it is funny what you said, Will, that they weren’t ever really developed to fix… the intention was not to fix asynchronous code paradigms. But people are using them for it and making it, turn asynchronous-looking code into synchronous-looking code.
WILL:
Right, yeah, precisely. It’s almost serendipitous. The examples you see with generators are traditionally, like you said, the Fibonacci sequence, some sort of lazy evaluated list. But it isn’t even a very interesting example. And almost anything to do with a generator on that front, you could do just as well with a class. But when it comes to actually managing callbacks and promises, the generator, the paradigm that we’re using when we write code for Koa or just with Koa in general, looks really nice. It looks, well really, traditional like you would expect in a more traditional language like Ruby or Perl.
GERRED:
It’s interesting. TJ Holowaychuk actually wrote a great article called ‘Callbacks vs. Coroutines’. And in that, it’s a great introduction when you look at it into actually building up a base flow control and really understand how that works with generators and how you’d end up doing that. And it’s a great precursor to all of the extra stuff that Co adds.
CHUCK:
So, I’m curious getting into this and heading back out toward Koa. Why are generators so critical to the way that Koa works?
WILL:
Koa has an approach to middleware that is distinct in the Node realm. It’s actually not… it looks very much like what you see with Rack in Ruby. But what Koa middleware can do that is different from, say Express, is middleware at the beginning can yield control to middleware that’s downstream. And then when the downstream middleware is finished, the control can come back upstream. So, a really classic example of middleware like this would be a logger, something that you want to actually print out to your log file. Let’s imagine that you want your log line to include the elapsed time of the request. So, it’s pretty typical. You’d want the logger to run first so it can find out what the start time was. And then it needs to yield to downstream middleware, all the way down to the application layer. And when everybody’s done and it gets back to the logger, you want to output the log line with the elapsed time.
Now, if you look at the way that this is done in other Node frameworks like Express or Connect, usually the logger middleware, it gets to run first, but then it just passes control to the next piece of middleware on the list and control never returns back to the logger middleware explicitly. So, the way that the logger middleware has to work in, say Connect, is it actually has to use the events. It has to listen to particular events on the Node response object in order to tell that it’s timed out, put the log line. And so, in that case, while you can achieve a similar effect, it gets a little more difficult to know exactly how all of the different middleware is going to coordinate at the end of the request.
But if you look at examples of Koa, it’s very easy to see what’s going to happen in what order. Top level, middleware runs, it yields to the next level, which yields the next level then it bubbles all the way back up and continues running where it had previously. And if you look at the way that the syntax ends up looking with the use of generator functions in something like Co inside of the Koa framework, it’s just very clear.
GERRED:
Yeah. It actually reduces a lot of the cognitive load that you’d otherwise have in [inaudible] through your middleware chains there.
WILL:
In fact, one of the things that if you look at the FAQ, one of the questions in there is about the motivation behind the design of Koa. And they point out that in Express, writing an app can be really lovely. A lot of people have used Express to great success, but that actually writing middleware for Express is rather difficult. And there are a lot of interactions that can happen between Express middleware that have to be carefully picked through. And the intention of Koa was to make it really easy to write middleware as well, so that they could move a lot of the goodies out of the core and into middleware in the community.
JOE:
And that’s one of the real powerful pieces of Node, is if you’re authoring Node, rather than just sticking stuff in, rather than just throwing crap inside of an already existing piece of how you’re handling some Node callback but actually to turn it into some nice looking middleware, and it’s almost Node’s way, a great way in Node to chunk up things into smaller pieces or basically to do abstractions, right?
GERRED:
Sure. And Koa has really embodied that heavily in that the Koa core is under 2000 lines of code. And I think that’s still the case. But it really just has the application and the context and the request/response handler. Basically, every module down to routing and serving files and everything else that came wrapped up in a nice package in Express is really split out. And if you go look at any given middleware, there are also these very tiny modules that advantage of Koa itself. And so, the amount of… Koa really takes on the Node philosophy of make everything these really small, easily obtainable modules that you can just dump into your application. And so, you can really pick and choose what you want inside of Koa. And the actual framework itself does almost nothing out of the box.
WILL:
Yeah. A really perfect example of this is that Koa does not have any built-in routing. And for a lot of people, a lot of app developers, that sounds crazy. But this perfect case where they were actually able to make the middleware layer powerful and easy enough to reason about that they felt comfortable letting the community support routers rather than making sure that they had a best in class router built right into the Koa footprint. And I don’t know what experience other people have had. But this is nice for me, because plenty of times when I got to write an app, I don’t need a fully complicated or expressive router system like the one that comes with Express 3.0. I’ll opt for something much smaller.
So, if you look at the Koa wiki, they have a list of community middleware, of known community middleware, and there are lots of options for routing that have different advantages. Some of them are much slimmer than the one you would get in Express but doesn’t feel like the framework is incomplete. And it’s very easy to reason about how those routers work. You’re not worried about the router middleware interacting incorrectly with some other important piece of middleware, because the way that middleware interacts in Koa is just much simpler than the way that middleware interacts in Express.
JOE:
And that does sound crazy to me, because doesn’t that mean now that I have to pick between 65 different routers?
WILL:
You know actually, isn’t that the classic Node problem? The bad side of lots and lots of small modules, it’s up to the community to moderate or curate the ideal modules. And sometimes, you aren’t totally sure which to use in a list of 20 or 30 things. I’ve run into the same things with templating languages.
AJ:
So, here’s the question though. It seems that you’ve taken Connect and Express and you’ve decided, okay, here’s the core stuff that everybody needs and that’s really important. And I’m just looking at this, KoaJS.com here, and it looks like it’s got a ton of stuff built in, actually. It handles headers really well. It looks like it’s got all the basics covered. And that, I would presume, is because you feel like there doesn’t need to be more than one way to set a header. Setting a header is really quite simple and you’re just going to do it this way, because the problem is well understood and the solution is well understood. So, it seems like what you’re saying is that for routing, the problem isn’t well understood or the solution isn’t well understood.
WILL:
Also, that there are a number of possible valid solutions that aren’t all necessarily compatible or contained within each other.
AJ:
So, give me an example of that, because it seems to me that routing is pretty cut and dry. It’s like you want to match up to a character, you want to get a variable, and you want to be able to potentially have another hardcoded set of characters after the variable.
CHUCK:
Can I jump in on this? Because it leads into a question that I have. So, in Ruby we have Rack. And Rack has become the basis for several different, in fact pretty much all of the web frameworks that you have in Ruby are based on Rack. And I look at Koa and I see something that’s very similar to Rack. And so, to answer AJ’s question, the routing in Ruby on Rails and the routing in Sinatra are completely different. And so, the approach is different depending on the problem you’re trying to solve and how you really want to think about how you manage mapping a path to a function or method that’s going to solve that problem. I am curious though. Do you see this becoming a framework for building frameworks?
GERRED:
I’d say so. And I’d say we already see that in that if you go and look at the wiki, there are already several full-on more opinionated frameworks out there. I think there’s Koala and Koa MVC and I think one’s called Opinion, where you get entire frameworks that are wrapped up, built on top of Koa. And so, you’re getting something more like something that looks like Rails or Padrino or Sinatra out of the box where you’re just ready to install it and go, but built on the same thing. So, you could ostensibly do the same thing you would do in Rack and Rails and take, say a Koala app and use the mount module and mount something else on top of it. And so, that’s pretty much exactly what you’re looking at.
CHUCK:
Doesn’t it also solve the problem that Joe brought up then? If you want to go with a toolset that is known or built to work together, you could go with one of those little bit larger frameworks.
GERRED:
Absolutely.
CHUCK:
And then they just tell you, use this routing library, use this ORM, use this to connect to this, use this other thing to connect to that.
GERRED:
Yes, exactly. I would look at Koa, and your point about Rack is very good. It’s great. I would look at Koa as more of that Rack-sized, or adding in that Rack functionality where it does take care of it. It makes known here’s how you set a header, blah, blah, blah. And any sugar you’d add on top of that comes in the form of modules or even more opinionated things on top of that.
WILL:
Another thing that occurs to me, and this is more about Co and about using generators to manage asynchronous code, is that when you include other people’s modules in Node land, one of the problems that we’ve had for a long time is that modules can do more than just have bad code paths. If you’re using, let’s say Ruby, you might use middleware and the middleware may have some bad code path that blows up. But when it does, you’re going to get a stack trace of where in that module things went wrong. And Node unfortunately, because of callback approach to things, sometimes modules will do truly horrible things like fail to call callbacks or call callbacks twice. So, then you get an error that’s in your code that’s the result of some bizarreness in some dependency that you’re using. And it makes things a little bit more fragile when you start to include other people’s modules.
And one thing that’s really nice about the Co approach and using generators to do asynchronous code instead of using the traditional callback approach to things is that try/catch and the more traditional approaches to trapping errors work better. And they tend to work a lot better. So, when something goes wrong in a piece of middleware in Koa, chances are you’re going to get a much more reasonable sense of where the mistake is. So, I find it a little bit less intimidating to take on other dependencies when the code is written with generators than I do when the code is written with callbacks.
CHUCK:
Well, I also want to point out that the approach that Koa takes itself, it gives you, how can I say this, a well charted path to adding functionality, because you just build another piece of middleware and you stick it into your stack where you need it.
WILL:
Yeah, one other thing that occurred to me about the routing was that sometimes you don’t have routing in an app. Sometimes an app actually just is maybe serving static files or doing something with static files. That’s a case where you might not even have a router. And the fact that the router is optional is nice.
JOE:
Yeah, that’s true.
CHUCK:
So, are you guys using Koa for projects that you’re currently working on and deploying to production?
GERRED:
Yes. I’m using it in one project right now. It’s a fairly sizable Koa app. It started its life as an Express app. And I have worked with one other client to convert an Express app, Express 3 app over to Koa, complete with its own ORM and everything else.
AJ:
What is that process like? Is there a wrap Connect module function that I can call that would return a Koa-compatible module? Or is it you rewrite all the modules that exist in Connect by hand, and Express?
GERRED:
For me, there was a significant amount of rewrite. I did one of those projects pretty early on. And I’m not sure what that, if that’s gotten a bit better. But for me, it was a lot of [by hand]. But a lot of the models, I was using Bookshelf.js in Connect.js which is a pretty extensible ORM.
AJ:
Woot, woot!
GERRED:
And a SQL generation library. And actually, a lot of that code got a lot simpler. And so, I noticed that things I was doing within routes got cut in about half where I could just actually yield the Bookshelf promise back. And these four, five-line routes got cut down to, or more, 10, 15-line routes got cut down to one or two lines. So, in that sense, actually rewriting it was a lot less painful than I thought it was going to be.
The biggest thing was swapping out that core and replacing out the router. I think that’s where Express ends up touching most of your application and all frameworks tend to touch most of your application. Once actually I got into the routes and started messing around, a lot of the stuff was working with promises because of code, because that’s in there. Instead of saying res.end with this thing that’s at the end of a promise chain or whatever, I could just say yield bookshelf find or where this thing, and Koa will handle the promise and return control back up the middleware chain when that promise resolves properly in the way that I expect it to.
AJ:
Right.
GERRED:
And so, that was a great feature and made that refactoring, that conversion process, a lot easier than I thought it was going to be.
AJ:
I imagine that anything you’re switching over to promises removes a thousand percent headache.
GERRED:
Oh yeah.
AJ:
Because then you’ve got errors will bubble instead of…
GERRED:
Exactly.
AJ:
Having to, in every single function, if error else, da, da, da, da, da. You just [makes popping sound]. If there’s an error, let it bubble all the way up the chain and I’ll catch it if I catch it.
GERRED:
Exactly.
WILL:
Yeah, and if you’ve already swallowed the promise Kool-Aid, then…
AJ:
Oh yeah.
WILL:
Co and Koa are amazing. They’re the perfect combination, honestly.
AJ:
I probably need to start drinking this.
CHUCK:
[Chuckles]
AARON:
Yeah, me too.
AJ:
Another.
GERRED:
And the promises is a perfect example because if you were to look at Express, you would have to get your promise and then call .then and your function. And from within that callback is when you’d actually send your response. Well, with Koa and Co all you have to do is say this.body equals yield and then your promise. And so, what that enables and one thing that’s a module that I like a lot is the filter, the JSON filter. So, what you can do is then resume control of that resolved response up the middleware chain to be modified on the way up. And so, writing middleware that actually can transform your body, I find is a lot easier with Koa, and for the same reasons Will talked about earlier, in that control is resumed all the way up your middleware chain up until the response.
AJ:
So, looking at the documentation it wasn’t clear to me. If I have a stream, I don’t…
GERRED:
Koa, actually I believe Co takes streams right out of the box. If you look in the main application.js of Koa…
AJ:
Okay. This is a really stupid, dumb question. How do I get to Co’s website? Because I’m searching Co JS and Co promises and Co…
WILL:
It’s under visionmedia. Github.com/visionmedia/co,
AJ:
Alright.
GERRED:
Yeah.
AJ:
Yeah, you actually have to type it in. It does not show up in search results.
GERRED:
And it may not be Co that takes streams and maybe Koa. Yes, it does. It does handle. Koa itself handles streams. Co does not out of the box itself take care of streams for you.
AJ:
Okay. It turns out that I cannot find it on visionmedia. [Chuckles] Oh.
It’s spelled K-O, right?
GERRED:
C-O.
CHUCK:
C-O.
AJ:
Oh, C. That’s why. That’s why. Because Koa was with a K. I was thinking Co was with a K. Alright.
GERRED:
[Chuckles]
CHUCK:
So, do you know where the name Koa came from?
GERRED:
I don’t. Will, do you know? I would assume, because it’s a play on Co, which is a play on coroutine. That would be my closest guess.
JOE:
Maybe he went…
CHUCK:
They didn’t name it after the campground?
JOE:
Yeah, maybe he went camping recently.
CHUCK:
Oh.
GERRED:
This could turn into a great conspiracy theory.
AARON:
Yeah.
CHUCK:
[Laughs]
JOE:
You know, I think it’s funny that there’s already a Koala framework out for Koa. I did a quick search and there are essentially no other words that start with K-O-A in the English language besides Koala and then a couple of words that nobody’s heard of.
AARON:
Like Urban Dictionary words or what? [Chuckles]
JOE:
No. One of them was like K-O-A-N, koan. I’d never heard of it before.
AARON:
Urban Dictionary, bro.
JOE:
[Chuckles] No, thanks. I’ll pass.
AJ:
What does thunk mean? Sorry, I’m taking us on a semi-related tangent.
GERRED:
A thunk is basically another word TJ came up with for callbacks. All it is, is a standard Node callback starting with error and then having your response in the other, as a second parameter.
AJ:
Okay.
GERRED:
So, he just renamed it thunks for…
AJ:
Thunk sounds very derogatory.
GERRED:
Yeah.
AJ:
I like that. It should be derogatory.
WILL:
Let me elaborate on that a little bit. So, what a thunk is, a thunk is actually a function that takes a callback as its only argument, that takes a Node-style callback. So, if you say, fs.readFile, that takes two arguments. It takes as filename and it takes a callback. But if you were to say, fs.readFile.bind and then bind it to some filename, you would produce a function that would simply take a callback. It would already be bound to the file that was supposed to be read. And that would be a thunk. So, the point of a thunk is that when Co was first created, when TJ first introduced it, you could only yield thunks. You couldn’t yield promises and other things like that. A thunk is the bare minimum thing to describe deferred work, deferred asynchronous work. And then later, promise support was added and for other things like that.
And so, it’s easier in a conversation like this to talk about yielding promises because everyone pretty much gets what a promise is. But in the case of Co, a thunk can be used in place of a promise really easily. And a thunk is sometimes easier to come up with than a promise in Node, because you can basically just bind to some function that has the typical Node parameters, where it takes a set of parameters and then a callback. You can just bind that to some parameters and then yield it. And then Co will run it and start your generator back up when the callback is called.
AJ:
And it looks like you don’t even have to get too fancy with the binding, because he’s got this thunkify where you pass in the function and it just assumes that you’re doing n-1 and that the last argument would be the thunk.
WILL:
Exactly.
GERRED:
Exactly.
WILL:
Yeah. And so, thunks are actually, even though I think that it takes a minute to wrap your head around them just because you probably haven’t heard the word, they’re actually more easy for working with Node-style callback functions than trying to wrap those things in a promise for instance.
AJ:
Yeah, okay. Yeah, that makes sense. So, I see it. So, you use this thunkify module, you pass in any Node function, and it returns to you a function that you pass in X arguments and then it returns a function that accepts the thunk thing.
WILL:
Exactly.
AJ:
Okay. Cool. It’s simplified.
JOE:
So, here’s your ‘the more you know’ moment. Thunk has actually been in use in computer programming for a long time. For example, back in the days when 32-bit and 64-bit OS’s were not ubiquitous, thunking was a process of making a 32-bit call compatible with a 64-bit call. So, it’s really a process of when two subroutines need to call each other but they’re calling methods or APIs aren’t compatible. A thunk allows one to call the other.
GERRED:
Oh, okay.
JOE:
And I really sound like I know what I’m talking about, but I’m actually just reading off Wikipedia.
AJ:
I knew you were, Joe. [Chuckles]
AJ:
Don’t worry. I didn’t give you too much credit.
GERRED:
Actually, Will and I had this conversation a while ago because he was talking about thunks and I was saying, “Hey. Thunking is like when you go from 32-bit to 64-bit.”
AJ:
I’ve never done that. Sorry. I don’t understand that problem. I’m sure it hurts. [Chuckles] WILL:
That’s funny. At the time I thought, “I don’t know if that’s the same thing,” but the way you described it just now I’m like, “Oh, that’s exactly the same thing. Yeah, you got it.”
JOE:
Right, yeah. Yeah, reading the Wikipedia article really cleared it up for me after our conversation.
WILL:
That should be somebody’s pick, Wikipedia.com. [Chuckles]
AJ:
The ultimate source of light and knowledge.
JOE:
Exactly.
AJ:
So, I’ll post a little like here for the notes, ‘Thunks vs. Promises’. That little snipped is a really good read/[inaudible].
JOE:
So, we had a conversation at the beginning before we really got into the show about Node 11. And I think it’d be interesting, worthwhile to just talk about through the fact that Koa only runs on Node 11 and what that means and et cetera, et cetera.
GERRED:
Sure. So yeah, as you just said, Koa requires generators. And as of right now, with a flag, I can’t remember. I have it [inaudible] now.
AJ: dash, dash harmony
GERRED:
dash, dash harmony. That is how you right now enable generators in Node.js and that is required to run Koa. So, if you’re on 0.10, if you’re on 0.8, sorry you need to go unstable. Hopefully, they are fully enabled in the latest stable version. But if you just run Node with --harmony, you’ll have generators. You’ll have a whole bunch of other awesome features as well, all those ES6 features.
But generator is one of many.
WILL:
Yeah. I believe that the generators will be present in Node 0.12 when that arrives.
AJ:
And promises will be native. But I don’t think they’ll be the best kind of promises.
WILL:
Are promises actually, I know that promises made it into ES6 Harmony, but are promises going to be in V8 then?
AJ:
Yeah. Well, they’re in Chrome and Firefox right now.
WILL:
Awesome. I didn’t know that.
AJ:
But they are a little bit crippled. If you’re familiar with using promises in Angular which is a crippled version of Q, then you’ll be even less satisfied with promises that made it into Chrome so far. It looks like, and I may have just done it wrong or maybe because it’s incomplete, but if you return a promise from a promise, you have to call .then and then pass in the resolves and reject, which isn’t terrible. But just returning a new promise or a different promise is a lot more intuitive. And that’s what you get in Bluebird that Bookshelf is using. And is it Stripe? I think it’s Stripe, is using that as well.
JOE:
I’m not really sure with your experience AJ, exactly how you were calling it. What you described, I know I’ve done that with ES6 promises no problem. But I might be not entirely understanding exactly what you’re talking about.
AJ:
I may have done it wrong. I may have done it wrong or it may have been just like a bug in that particular version, because it’s still not solid. But it’s implemented.
WILL:
But I know that in Q you can return a promise from a then. And when that promise is fulfilled, it will fulfill the next promise down the chain.
AJ:
Right.
JOE:
Right.
WILL:
And that’s promises/A+. Do the ES6 Harmony promises conform to promises/A+?
JOE:
Yes.
WILL:
Oh, okay.
JOE:
So, you can definitely do that.
AJ:
Okay, good.
JOE:
I know that RSVP.js is right now the best polyfill for ES6 promises.
AJ:
Well, there’s one that’s called ES6 Promises.
JOE:
Yeah. That’s a subset of RSVP.js. So, RSVP is a little bit of a superset with a few more pieces of functionality than ES6 Promises. But right now, Node 11 does not support the ES6 Promises.
WILL:
Yeah, I don’t think those are in the version of V8 that Node 11 is built with.
AJ:
Oh. Oops.
JOE:
So, that begs another question. What other features of ES6 do you use, since you’re already on Node 11 and already running with the Harmony flag on?
WILL:
[Chuckles] There’s only one that I use on purpose, and it’s really funny. It’s Array.prototype.find. [Chuckles]
WILL:
Which is just like Array [inaudible] filter and then getting the first element out of it. But it shortcircuits.
AJ:
[inaudible] statement, promise is in Node 11, just FYI. Sorry.
WILL:
Oh, interesting.
JOE:
Promise is in Node 11?
AJ:
Yeah, it is. I just installed it a few minutes ago and I just ran node --harmony new promise. It’s a function.
GERRED:
And there you go.
AJ:
Yeah, so it’s there.
JOE:
Funny. The [inaudible] table, compatibility table must be out of date. The universe looks up the compatibility table. It must be out of date. But I’m surprised that you don’t use let. You got maps and sets. Of course, they’re only useful under certain circumstances, right?
GERRED:
I’ll use let. I’ll use const. I’ll use the arrow functions. The arrow functions are just nice, if you’re not a CoffeeScript user. I think those are the only ones I use.
WILL:
I’m looking forward to parallel assignment, to destructured assignment. That’s going to be nice.
AJ:
Oh, yeah.
GERRED:
Yeah.
JOE:
Yeah. It’s surprising of all the ES6 features how few are actually supported yet by Node. The browsers support a lot more of ES6 than Node harmony flag does.
WILL:
And when you say the browser, you mean Chrome itself?
JOE:
Yeah, yeah. The current release version of Chrome, even the release version of Firefox. If you go to the beta versions of Firefox, there’s even more supported.
WILL:
Firefox had generators, I want to say in 2010.
AJ:
Well, yeah…
WILL:
But they were not, the spec has changed. So, now Firefox generators are weird and don’t work the same.
JOE:
You know, when I was using generators, I was using them with Firefox nightly, the beta Firefox. And I don’t notice any weirdness. But that might be just because I wasn’t using the same way as you.
WILL:
It also may be that they have changed. The last time I really looked at it was a number of years ago. But at that point, they had a different API. They didn’t return an object that had next and value.
JOE:
Oh.
WILL:
They had [more than one] way of running the generator and some ways passed value in and some ways didn’t. And you could ask if the generator was done.
GERRED:
That was the send function, wasn’t it?
WILL:
Yeah, yeah. And it was actually confusing when I got started with generators because Google still liked to send me to those bits of documentation, which do not at all help.
JOE:
Right. Yeah no, that’s definitely changed now. Generators in Firefox definitely work the same way as the ES6 spec.
WILL:
That’s good news. And hopefully, they’ll rid the internet of their out of date documentation.
JOE:
Yes. Yes, we need a cleanup, like a garbage collector on the internet.
WILL:
Some way of just saying that this is deprecated. Oh wait, you can just put the word deprecated on the page. I guess that would work.
AJ:
No, because you still have W3 Schools. [Laughter]
WILL:
I guess you have a Chrome toolbar that just puts the word deprecated on all of those pages. [Laughter]
WILL:
If you could have a Chrome toolbar that adds ads to all of your Netflix movies. [Chuckles]
GERRED:
Like the right to be forgotten. One thing I wanted to mention that we really haven’t talked about is the performance of generators. And I’m trying to find it, but there was a write-up comparing straight callbacks to generators to promises. And it turns out generators are really fast. And you’re only taking a very slight performance penalty. I’ll find the article. But you’re only taking a very slight performance penalty using generators instead of the traditional callback oriented flow control in Node.
AJ:
What’s that penalty for?
GERRED:
Well, as far as flow control goes, you are adding a level of overhead and ultimately it’s still operating on the callback at the end of the day. So, because Co is still operating on your promise or on your callback in the case of that, it’s doing a little bit more in putting it into a generator and whatnot. So, really, more code, more steps through, slight performance penalty. But the overhead it adds has turned out to be pretty minor.
WILL:
Which is pretty exciting, and I don’t know enough about the V8 internals, but I doubt that generator performance has gotten the kind of attention that other things have so far. So, it’s good news that we’re not saying, “Oh, generator’s really slow. But hopefully they’ll get fast in the future.” It seems like they’re already totally acceptable.
JOE:
That’s good. That’s cool.
AJ:
And realistically, they could be just as fast, because it’s code. It goes into a compiler. It can mangle it, do whatever it wants. It could destructure it back into callbacks if callbacks were faster.
GERRED:
Sure.
WILL:
One of the things, it’s funny. Talking about it is interesting and hopefully people will go and take a look. One of the things I like to point out to people is I show them examples of code written with generators, not just Koa but stuff written with Co, is I like to point out and say, “Look how boring this is. It’s just so boring. It’s just exactly what you would expect the code to look like.” There’s no weird counter to count all of the tasks to see if you’re done at the end of every callback. There’s no bizarre unrolled recursive loop that’s gobbling away your arrays. You can just, ‘for i = 0’. It’s really cool, actually. It’s nice that you have try/catch back. It’s almost funny that for people who have been stuck or privileged to use Node for the past three years that these things are so exciting. But they are really exciting. It’s exciting to have boring code again.
JOE:
[Chuckles] I like the way you said that. That should totally be our tweeted quote of the episode.
AJ:
Yeah, I agree. That’s a good one.
JOE:
So, do you guys feel like Koa is going to essentially replace Express? Or do you think Express is too much of a behemoth for Koa to really have a chance of doing it? Is Koa going to be more along the fringes? Used for people that need something with less to it so that they could build it up and rather than throwing down Express and just having everything built-in?
GERRED:
You know, I think that when Koa came out, it was intended to be a spiritual successor to Express. And since then, think we’re headed to Express 4 if Express 4 isn’t already out. And I think there is room for them to live side by side. Whether or not it will stay sidelined, I’ve seen a lot of excitement over generators for the past few months. A lot more than I’ve seen previously.
So, I think that Express is really rooted where it is right now. But I think as systems grow, I think generators and Koa makes a lot more sense. Having worked with Express on larger applications, it’s not an experience I really prefer to repeat. And Express could not just go and add generators in and still be Express. If you’ve ever tried to work with generators inside of an Express app, it’s difficult if not impossible to do. There’s a module that tries to do it that I didn’t find to work. But if you’re wanting to get away from that nested callback structure and move towards that, you really can’t do that work on Express.
AJ:
What I’m hearing is, “Yes. Express is dead and Koa’s the way of the future because if you want to move forward, there’s only one way to do it.”
GERRED:
Yeah.
WILL:
I think that if you really look at the Node community, there’s an interesting, the conversation about callbacks is fascinating. If any of you have lurked on the Node mailing list over the past three years, every once in a while some new person will wander in and say, “Gosh, this is really cool. I really want to use JavaScript on the server side but callbacks are really confusing.” And then the Node mailing list will explode. For four days no one will be able to say anything, because that flame war is never going away. And if you look at it, sometimes a flame war like that, this argument over whether or not callbacks are sufficient is really rooted in a big part of the Node community. It’ll always be part of the DNA of Node that a lot of people are adhering to the callbacks were all we ever needed way of life.
AJ:
I disagree. I think that the problem was that everybody had a different opinion. Everybody had a different solution. There were five different competing standards and then everybody wanted to make one to rule them all, so now there are six competing standards and seven and eight and twelve competing standards. Now, we have something in JavaScript native that works.
WILL:
Exactly. That’s what’s exciting, because you’re totally right. For whatever reason, Ryan and then later Isaac, they didn’t provide any input to the community about how we were going to do this. They just said, “Well, callbacks are what we have and I’ll let you guys figure out the rest.” And I think that’s why the argument was never over. And generators does settle the argument in one big way, that we know that this is built in. and actually, it’s just as exciting to see promises make it into ES6 because it settles it. A different community has settled the issue. They’re saying, “We have generators and we have promises. These things are part of JavaScript now.” So, the Node community can do things however they want. And there will be lots of fragmentation. But at least we have a couple of new tools in the toolbox that are essentially blessed as standard tools.
So, I think you’ll see a lot of people, I myself for instance used Fibers for a long time, which is an awesome module but it’s scary because it’s a hack of the way V8 works. It doesn’t require recompiling V8 but it’s an odd module written in C++. And for me, I feel like I’m coming out of being a second class citizen into being able to really fully embrace Node. I was never fully satisfied with callbacks. And now, the generator approach is absolutely good enough for me. It’s really exciting. And I think you’ll see a lot of people who feel like I do about it. So, for those people, Koa, it’s not about replacing Express. I never used Express. Express didn’t fit my needs ever. I was always using some other approach or rolling my own. [Chuckles]
WILL:
Because the Node core is so cool that it’s hard to ignore. But basically Koa, I’m really happy that
TJ and Jonathan Hong provided all of their experience. There are guys who have worked on the Express framework from day one. And Koa is really beautiful. It’s really slick. It’s not some upstart who’s never done this before, here’s my version of this. It’s some people who have years and years of experience, of deep experience providing something that works extremely well with this new generator approach. So, while I don’t think Express is going anywhere, lots of people will stick with it, for people in my position, Koa is the first web framework that I’m excited about in Node.
AJ:
Yeah, well I think that it’s interesting. Because when Node started, there was a bunch of people from the Ruby community that basically did all the things that Ruby got wrong, they did them right. And now, it’s interesting because in Node, I think that there’s going to be a shift to doing things the right way, even though there’s so much entrenching in doing it the wrong way. Because the right way is being standardized and blessed. So, I hope to see more frameworks like Koa pop up that provide clear and clean patterns to get these things done.
WILL:
Yeah, absolutely.
CHUCK:
Alright, well should we go ahead and do the picks then?
AJ:
Yeah, I got to get going.
CHUCK:
Alright AJ, you want to start us with picks?
AJ:
I pick Koa, because I think it’s awesome. I think it’s absolutely awesome.
And I also pick Firefox OS. If you are listening to this podcast, then you’re the type of person that should either get a ZTE Open C which you can get on EBay for I think 80 bucks. There’s the ZTE Open which is 20 bucks left but I don’t think it makes sense to get that one. And then there’s the Flame that just came out that is $200. And I just ordered one but I haven’t gotten it yet. But I expect that it will be much better. It has more peripherals and stuff on it. Firefox OS is cool because it allows you to be able to access, I guess it’s like Cordova but better, because you have more access to more APIs in JavaScript and you have this nice open source operating system that’s based on Gecko that if you were really cool, you could get in there and actually make the phone do whatever it is that you want for reals. Oh JavaScript. Love it.
CHUCK:
Joe, what are your picks?
JOE:
My first pick is going to be a little self-serving. On Monday, so a few days ago, I was on the podcast Hello World, which is all about how somebody got their start in computer programming. So, I spent some time talking with Shawn Wildermuth about it. And one of the things that came out of that that was pretty funny was I actually spent a couple of years programming on paper. And if you’re interested in hearing the story, it’s a pretty short podcast. It’s 20-30 minutes long. And just all about how I got started in computer programming, how I got my first job, how I got into Angular, et cetera. So for me, my first pick is that Hello World podcast.
AJ:
That’s also my third pick. [Laughter]
JOE:
My next pick is going to be the game Council of Verona. It’s a card game that’s set in the Romeo and Juliet setting, Verona. And it’s a very fun, strategic game where you’re trying to place down people. It’s really not fit to explain very easily. But it’s just really fun. Great setting, easy to pick up, fun strategy, easy to play with a small number of people, so I really enjoyed that game.
And my third and final pick is going to be my new phone. I picked up an HTC One M8. So, I have the HTC One. And I really liked it, mostly because I liked the front, the speakers that face the front. Because I’m always showing people YouTube videos or wanting to maybe listen to some music and I don’t have my headphones. So, I have the option to get an upgrade for free to the new version of the HTC One which is the M8. And it’s pretty much just like the HTC One. They say the speakers are better. I don’t know. But the one thing that I really love about it is it’s got this new camera mode where you could take a picture and it will end up in the corner, also take a picture of you as you’re taking the photo. So for example, you could be out traveling around and want to take a picture of something you see that’s cool but also capture your face as you’re taking that picture.
And I think that’s a pretty cool and ingenious little invention. So, I’m going to pick the HTC One M8.
CHUCK:
I so want it to be an M80.
JOE:
[Laughs] Yeah.
CHUCK:
Another side note, I actually lived in Verona for six months
JOE:
Really?
CHUCK:
Yeah. So, I’ll go ahead and throw some picks out there. I’ve been using a new task management system. It’s called Redbooth. It used to be Teambox. And I’ve really been liking it. You can integrate it into your email. I actually use Gmail and they have a Gmail plugin for Chrome. So, I’ve been using that and it’s been super awesome. And so yeah, I’ll pick that. And I’ll pick the plugin there.
I also just finished the Wheel of Time series. The first five books are pretty interesting. And then it goes into a lull for about five books. And then the last three or four books are actually pretty actionpacked too. So, I enjoy those. If you like epic fantasy, then it’s an epic series because it’s really freaking long, but really good. There are 14 books in the series. And those are my picks.
Gerred, what are your picks?
GERRED:
So, I’ll start off with Elixir Sips. I’ve been working my way through, I’ve used Elixir for a little while. But the episodes, it’s a podcast about Elixir. And I think there’s something near 90, 91-ish episodes right now. Great series. He does a great job explaining everything in Elixir. If you want to get into the language, use it more, it’s a great resource.
My next pick is going to be TJ’s article on ‘Farewell Node.js’. TJ is leaving the Node.js community focusing more on Go. But he’ll still be maintaining Koa. So, he’ll still be actively involved in that project. But outside of that, he is changing his focus. He’ll also be working with Co and the related libraries for that.
And then my last pick is Loop Crate. Loop Crate is a service that basically will send you a monthly box of just different things. It’s themed out. It’s definitely for nerds. And you spend 13, 14 dollars a month and they send you a whole bunch of stuff, shirts. And this month’s theme is villains. So, check that out. It’s pretty awesome.
CHUCK:
Very nice. Plus one on Elixir Sips. They’re pretty good. Josh Adams, I’ve talked to him a few times and he’s super pumped about Elixir. So, definitely check those out. Will, what are your picks?
WILL:
My first pick is a module I found, I think on Hacker News called Fast.js. And it’s by the team over at Codemix. The premise behind Fast.js is that it’s actually possible to write certain functions in JavaScript that are faster than their built-in counterparts, at least in V8. So, for instance you can write something that is like Array.prototype.foreach but is faster than Array.prototype.foreach. And the first time I saw that, I did a double take. I would have assumed that the built-in native functions were as fast as those things you get. But the reason they’re not is because first of all the V8 compiler is incredibly efficient. And a lot of times the JavaScript to machine code compilation is just as good as the C to machine code compilation.
But the other reason is because the ECMAScript standard has a bunch of edge cases that are not normally seen in the wild. So for instance, arrays can be sparse in JavaScript. And if you do foreach on a sparse array, it’s supposed to skip all of the elements that have never been set, whereas a naïve implementation of foreach would just call the callback with undefined for each of those elements. And sparse arrays are really unlikely to be used and the consequence of this is that the Fast.js version of foreach is faster than the V8 built-in version.
And that one’s not the most impressive. There are some other ones. It has a version of bind that is seven times faster in some cases than the bind in native V8 for the same sort of reason. It doesn’t follow all of the standards but most people never even notice. So, it’s my pick not because I think people should be using Fast.js necessarily but because it was interesting to see. I had these assumptions about performance and they were just totally wrong. It was interesting to see what I learned when those assumptions were challenged.
My second pick, and I’m changing my pick at the last minute, is my new Duracell Deep Cycle Marine battery. I’ve been building a swamp cooler to take with me to the dessert to keep my tent cool. And this has been a really fun nerdy project. I got to do all sorts of electrical work and things like that. And the biggest challenge has been figuring out how to power the thing. I went through solar panels and thought about a generator and things like that. and ultimately I discovered something that maybe a lot of people already knew, but there are these awesome things called deep cycle marine batteries, which you can take out into the dessert fully charged and run a swamp cooler like this for three or four days without any problem. So, that’s my other pick, is my awesome new toy.
CHUCK:
Very nice. Thanks for coming, guys. I really appreciate you coming and sharing your knowledge of Koa with us. If people want to find out more or get a hold of you guys, what’s the best way to do that?
GERRED:
Best way to get a hold of me is through Twitter. I am justicefries on Twitter.
WILL:
And everything about me you can find on my website, which is WillConant.com and my Twitter handle and GitHub user name are there.
CHUCK:
Alright. Well, thanks for coming and we’ll catch everybody next week.
[Hosting and bandwidth provided by the Blue Box Group. Check them out at Bluebox.net.]
[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]
[Do you wish you could be part of the discussion on JavaScript Jabber? Do you have a burning question for one of our guests? Now you can join the action at our membership forum. You can sign up at
JavaScriptJabber.com/jabber and there you can join discussions with the regular panelists and our guests.]