JS.Next: ES6 / ES2015 JS.Next: ES6 / ES2015

Proper Tail Calls: ES5 vs. ES6

Check out a free preview of the full JS.Next: ES6 / ES2015 course:
The "Proper Tail Calls: ES5 vs. ES6" Lesson is part of the full, JS.Next: ES6 / ES2015 course featured in this preview video. Here's what you'd learn in this lesson:

Aaron uses the Fibonacci Sequence to illustrate the differences of Proper Tail Calls in ES5 and in ES6. He also offers a few final thoughts about using recursion in JavaScript.

Get Unlimited Access Now

Transcript from the "Proper Tail Calls: ES5 vs. ES6" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Aaron Frost: I feel bad for even showing a Fibonacci example. What's that law, if you talk long enough about anything on the Internet, it'll go back to the Nazis or to Hitler? It's like some law, I can't remember the name. Does anyone in the chat have it? Anyway, there's a law that the longer you talk about someone online, it's eventually gonna go out to some crazy extreme like tied to Hitler.

[00:00:25] And it does, like the the longer it goes the likeliness of that happening increases. I think the longer you talk about any language on the planet, someone's gonna try to make fun of it by saying you can't do Fibonacci correctly, right? Even though none of us and none of the people we know besides for home Godwin's law, that's Godwin's law is, it ties to the Hitler, the percentage of references to Hitler goes up after time.

[00:00:49] So, thank you, Steve W. So yeah, and people have definitely criticized JavaScript for not being able to calculate Fibonacci, NBD though right, who cares? So pre ES6, this is what Fibonacci looked like in JavaScript. So you'd have your Fibonacci function and you'd say, hey I want the third number in Fibonacci, and it would return a 2.

[00:01:21] And you'd say, cool give me the tenth one now and it would say, cool, 55. And then you'd say, okay, give me something bigger than that 10,000 limit that we talked about earlier, remember? And it would say, all right, dude I know how to do that, it's called a range error, like it knows exactly what to do there.

[00:01:37] And so yeah, however I will say that this call to Fibonacci was proper tail call because, well it is actually a tail call. Because it doesn't need anything to calculate like it could release a stack if the language let it, but it's not really. Anyway, it was written correctly is all I'm trying to say.

[00:02:03] And now with ES6 the same code, so each call adds another stack, each stack needs more memory and then the memory eventually is gonna run out. And you have to wrap up this with a try catch if you don't want to kill your execution. So with ES6 though it will say, yeah, I know how to do three, I still don't know how to do ten but I also know how to do Fibonacci to that number.

[00:02:31] Has anyone calculated that? It's like a lot of bloody number, it's really a long number. Okay, I don't know how many digits long it was, like I did it online though and it was really, really long. So yeah, so this is what it looked like in ES6. So the same code that we had on the previous slide, on ES6 it just will work.

[00:02:53] So if you got something that wasn't working, I mean you didn't release it, but it would just work in ES6. And if you did have recursion in your code and it was proper recursion, like you wrote it's where it could release the stack if it didn't need it.

[00:03:08] Your code could get faster like just by grace of the the runtime being able to handle that stuff better. So proper tail calls only work in strict mode, so if you don't use strict mode you're gonna get it. So that's something you're gonna wanna turn on. And then optimize your code if you do recursion, to where it can use this method of releasing the current stack.

[00:03:34] If you make a method call, pass it everything it needs so it can release the current stack. And actually this is not the worst idea for every method call that you did, cuz it's not just recursion that's going to benefit from this kind of stuff. Any method call that doesn't need the prior stack, that's running in strict mode would get the benefit of this memory consumption.

[00:03:55] So if all your methods and that might make your code look ugly if you're passing everything into the method that it needs, like it could kill your code. But I'm just saying you may want to think about it, right, for the future. So that's PTC, any questions, proper tail calls, we're good, anyone online?

[00:04:17] My man, any questions online?
>> Speaker 2: I think we're all caught up.
>> Aaron Frost: We're all caught up? Okay, cool.
>> Speaker 2: Is there any difference on my own questions? If I pass an object with the key value pairs and stuff, does it know-
>> Aaron Frost: No, as long as that call that's right before the return.

[00:04:36] As long as that's a call to another method and inside of that call, if it's back to itself, it doesn't need any other variables from the current scope, like you're passing them into it. It can really it will be like ES6 will enable it to release that current stack, and and just kind of go on with a new one.

[00:04:54] Doesn't matter what you're passing it, you can pass it as a function, as object nothing. Yeah?
>> Speaker 2: One thing that did come up earlier, I wrote down, with ES6, there's a lot of the features in CoffeeScript in it, so why learn CoffeeScript, he was asking.
>> Aaron Frost: Exactly, but I say that and it sounds like I'm really mocking copy script.

[00:05:20] But I'm not because we're gonna see a lot of really cool features today that came from it. So, I'm not trying to say CoffeeScript didn't serve a point and doesn't still serve a point. It was like a breeding ground for a lot of really important functionality, okay. Another breeding ground that I didn't actually talk about, I actually kind of skipped over this was.

[00:05:41] So when the two camps were like hey, we're not gonna agree on ES4, ES3 or ES4, we're not gonna agree. Mozilla was back at headquarters implementing the features that they wanted, right. So we're gonna hear about let, we're gonna hear about destructuring, we're gonna hear a lot of stuff that Firefox has had for over half a decade.

[00:06:07] Because they just went back to headquarters and implemented it. And honestly that was how they got some of the best feedback, like when they came to implement any ES6, they're like well, we've found the blah, right? And the CoffeScript guys would say well, when it comes to arrow functions, and fat arrows and skinny arrows, we don't think you should have two, you should just have one.

[00:06:24] If there's a lot of good feedback that can come from a CoffeScript, or like a Mozilla Trailblazing functionality without it being part of the standardization body. So that was a good question, again. Again, I'm not arguing that we should write CoffeeScript. However, I'm also not mocking people that do and I'm not saying that it didn't serve purpose, yeah?

[00:06:45]
>> Speaker 2: There's a question in the chat about ES6 and how would you write a non PTC Fibonacci, will that just work across the board?
>> Aaron Frost: I should've written that ahead of time. It's not gonna work across the board. Some people when they write it, here I'm just gonna pull up a console.

[00:07:05] They write it so that inside the code, you'll be fib and then (n) +. So, in their code they'll say, return fib(n) + fib(n-1) or something like that, okay? The last instruction getting evaluated on that return call is not either of the fib calls. It's the addition of the two results together.

[00:07:45] So and that's why I call it a close call because you're like, dude, it's in the return spot or it's in the tail spot. It's a call to a method, it's a tail call. This is not a tail call because the last instruction it's gonna execute is now add the result of this call to the result of this call.

[00:08:05] The addition is the last instruction that's gonna happen, so that looks this looks like a tail call, totally not a tail call. And if you roll your Fibonacci like this, you'd still have your 10,000 stack cap, and it would die. And probably less, because there's significantly more variables and code in there.

[00:08:27] Good question, did anyone else have that question? Good question, any other questions? No, we're good, okay. So remember I said I was gonna want you guys to try it out, I was like hey guys, we're gonna talk about it and we're gonna try it out. And so if you look at proper tail calls, it's like the saddest, it's like the loneliest number right.

[00:08:50] Like nobody is doing it, and tracer can't do it, cuz tracer has a lot of these features but it doesn't have a PDC because tracer, it compiles from ES6 into ES5. So it can affect the runtime environment, it couldn't make tail calls, it couldn't make the recursion happen, if it even wanted to.

[00:09:18] And so, but no one else has implemented it yet, not even Firefox,Chrome hasn't. So yeah, it's just kind of a sad, sad little feature so we're just gonna keep going. This is the only one that's like that though. Everything else you guys will be able to try, so