#fronteers14

Kyle Simpson - Choose your own JS adventure

Fronteers 2014 | Amsterdam, October 10, 2014

Yeah, yeah, ES6 is awesome. Everyone knows that. We're all excited about not having to write the word 'function' anymore. But, isn't it about time we stop obsessing so much about what TC39 puts into the official language spec?

Let's talk about making and using tools (built in JS, of course!) to customize the language itself to your own liking. We'll talk about macros, code parsers and transpilers, and other fun tricks to put the control of the language back in your fingers.

Make your own JavaScript. And no, that doesn't have to stop you from playing nicely with others.

Slides

Transcript

00:01.195 --> 00:02.570 (jake archibald) --a big Fronteers 00:02.570 --> 00:03.870 welcome to Kyle Simpson. 00:09.330 --> 00:11.310 Appreciate it very much, Jake. 00:11.310 --> 00:12.810 They gave us the whole stage to use, 00:12.810 --> 00:14.726 but none of the other speakers have done this, 00:14.726 --> 00:16.950 so I'm going to take a little bit of artistic liberty 00:16.950 --> 00:19.204 and I'm just going to start out my talk over here. 00:19.204 --> 00:20.870 And I think I'll make myself comfortable 00:20.870 --> 00:23.390 so I'll go ahead and kick off my shoes, 00:23.390 --> 00:27.839 just like Jake did and hi, Marten. 00:27.839 --> 00:29.130 Would you take my shoes for me? 00:29.130 --> 00:30.160 That would be awesome. 00:30.160 --> 00:30.993 Thank you very much. 00:30.993 --> 00:32.000 I appreciate it. 00:32.000 --> 00:33.330 A big hand for Marten, please. 00:33.330 --> 00:33.829 Thank you. 00:38.220 --> 00:40.840 In all seriousness, the hospitality of this conference 00:40.840 --> 00:43.580 has been fantastic, just top notch 00:43.580 --> 00:45.304 and I do a lot of conference speaking, 00:45.304 --> 00:46.970 so I can say with authority that they've 00:46.970 --> 00:48.260 done a really great job. 00:48.260 --> 00:50.770 So thank you all very much for having me here. 00:50.770 --> 00:53.727 So we're going to start out just a little bit informally. 00:53.727 --> 00:55.810 I just would like to know, not that I can actually 00:55.810 --> 00:58.690 see you because of the bright lights, but I am just curious. 00:58.690 --> 01:01.120 How many of you have ever had a piece of code 01:01.120 --> 01:03.240 that you wrote that broke and you weren't sure 01:03.240 --> 01:06.450 why it was broken? 01:06.450 --> 01:09.930 I'm guessing by the laughs and by the noises that most of you 01:09.930 --> 01:11.407 raised your hand. 01:11.407 --> 01:12.740 Here's a more profound question. 01:12.740 --> 01:14.320 How many of you have written a piece 01:14.320 --> 01:16.680 of code and it worked and you still 01:16.680 --> 01:19.230 didn't know why it worked? 01:19.230 --> 01:20.590 Yeah, I thought so. 01:20.590 --> 01:23.850 So I actually-- Sartre, if I'm pronouncing 01:23.850 --> 01:27.160 that correctly, he's famous for the "hell is other people" 01:27.160 --> 01:30.134 and then we've rephrase that in the development industry to, 01:30.134 --> 01:31.300 hell is other people's code. 01:31.300 --> 01:35.300 But I'll tell you that hell is not understanding my own code. 01:35.300 --> 01:36.970 And what we're going to get into today 01:36.970 --> 01:39.937 is this idea that source code is really for the developer 01:39.937 --> 01:42.270 and it's not for the computer and I'm going to come back 01:42.270 --> 01:44.630 to that theme several times. 01:44.630 --> 01:46.490 So just to kind of set some expectation, 01:46.490 --> 01:48.420 the running theme for this conference 01:48.420 --> 01:50.510 thus far seems to at least, to me 01:50.510 --> 01:53.190 have been sort of pushing back your boundaries 01:53.190 --> 01:55.999 and saying you were using that technology or that practice 01:55.999 --> 01:57.540 incorrectly and I'm going to give you 01:57.540 --> 01:58.789 a different way of doing that. 01:58.789 --> 02:00.450 And in that same theme, this talk 02:00.450 --> 02:03.210 will kind of challenge some of those perspectives 02:03.210 --> 02:04.680 that you may have had. 02:04.680 --> 02:07.610 So on the first day, we saw, of course, CSS be taken down 02:07.610 --> 02:10.008 and this whole idea that there is best practices 02:10.008 --> 02:11.650 was sort of challenged and then we 02:11.650 --> 02:14.108 were told that we shouldn't even be writing markup anymore. 02:14.108 --> 02:15.770 We should let tools to all that for us. 02:15.770 --> 02:17.870 And that's been a running theme through many of these talks 02:17.870 --> 02:19.600 and I'm excited about that because I 02:19.600 --> 02:22.400 feel in its own little way that this talk can sort of fit 02:22.400 --> 02:22.910 into that. 02:22.910 --> 02:25.870 So if any of you remember the old school choose 02:25.870 --> 02:27.560 your own adventure books, we're going 02:27.560 --> 02:29.270 to have that sort of style here. 02:29.270 --> 02:32.020 It's choose your own adventure in JavaScript. 02:32.020 --> 02:33.970 And so I'm known as get a fine line. 02:33.970 --> 02:36.290 If you have any thoughts or feedback 02:36.290 --> 02:38.240 that you'd like to provide, please do 02:38.240 --> 02:40.330 feel free to reach out. 02:40.330 --> 02:43.410 One thing I want to bring up here and it's not entirely self 02:43.410 --> 02:45.951 serving although mostly so is that I have a series of books 02:45.951 --> 02:47.450 that I've been writing on JavaScript 02:47.450 --> 02:49.140 and it's called "You Don't Know JS" 02:49.140 --> 02:51.589 and you can see those books for free online. 02:51.589 --> 02:53.130 You can also buy them because they're 02:53.130 --> 02:54.407 being published through Riley. 02:54.407 --> 02:56.740 But I don't bring that up just to sell books, I actually 02:56.740 --> 02:59.410 bring it up because it brings up an important mindset that I 02:59.410 --> 03:01.160 want to make sure everybody understands 03:01.160 --> 03:02.285 when we get into this talk. 03:02.285 --> 03:03.524 This is sort of a meta talk. 03:03.524 --> 03:04.940 It's not really a programming talk 03:04.940 --> 03:07.210 to tell you how to write JavaScript, 03:07.210 --> 03:09.660 it's to empower and inspire you that you 03:09.660 --> 03:11.900 can come up with your own ways of writing JavaScript. 03:11.900 --> 03:14.460 So if you've struggled with writing code 03:14.460 --> 03:16.120 and you've struggled with the language, 03:16.120 --> 03:18.856 the first step, of course, is to understand the language better 03:18.856 --> 03:20.480 and hopefully, these books can do that. 03:20.480 --> 03:22.771 You really do need to understand the language in a very 03:22.771 --> 03:25.120 deep level, but this next step is sort of the step 03:25.120 --> 03:26.710 that I'm proposing today. 03:26.710 --> 03:30.889 So we're going to jump right in with invoking the whole choose 03:30.889 --> 03:31.680 your own adventure. 03:31.680 --> 03:33.805 You're Branden Iche and you're employed at Netscape 03:33.805 --> 03:36.250 in May of 1995 and your boss asks 03:36.250 --> 03:39.635 you to design a new language from scratch for the browser, 03:39.635 --> 03:41.510 but he gives you only 10 days to complete it. 03:41.510 --> 03:43.400 So choose your next adventure. 03:43.400 --> 03:46.640 To agree and give it your best shot, turn to page 39. 03:46.640 --> 03:49.640 To laugh and walk away, turn to page 262. 03:49.640 --> 03:55.110 And many of us probably wish that we'd turn to page 262, 03:55.110 --> 03:57.170 but we'll go to page 39. 03:57.170 --> 04:00.220 And then the next adventure then we get to choose. 04:00.220 --> 04:02.300 You've learned the ins and outs of JavaScript, 04:02.300 --> 04:04.460 but there's lots of things that still bug you. 04:04.460 --> 04:06.910 For example, this empty array is equal to the negation 04:06.910 --> 04:07.870 of an empty array. 04:07.870 --> 04:09.830 That's just too unbearable for you to go on. 04:09.830 --> 04:11.500 So choose your next adventure. 04:11.500 --> 04:14.910 Will you give up on JavaScript and move on to the language Go. 04:14.910 --> 04:16.490 And then you should turn to page Nan 04:16.490 --> 04:19.029 and to explore your own custom JavaScript, 04:19.029 --> 04:22.410 turn to this exponential floating point page. 04:22.410 --> 04:24.310 So enough of this silliness out the way, 04:24.310 --> 04:28.190 but I'm going to invoke right from the very beginning 04:28.190 --> 04:30.560 this idea that we need better tools. 04:30.560 --> 04:33.380 Whenever we run across problems as developers, 04:33.380 --> 04:35.950 we oftentimes will blame the tool set 04:35.950 --> 04:37.340 that has been presented to us. 04:37.340 --> 04:39.180 For instance, we might go in the language. 04:39.180 --> 04:40.280 We might blame our editor. 04:40.280 --> 04:42.330 We might blame some sort of process. 04:42.330 --> 04:44.490 And rather than turning an eye towards blame, 04:44.490 --> 04:47.160 I'd rather this talk be turning an eye towards, 04:47.160 --> 04:49.990 let's stop focusing so much on the standards and the processes 04:49.990 --> 04:53.060 that we already have and turn our attention and our focus 04:53.060 --> 04:55.635 on creating an inspiring better tools. 04:55.635 --> 04:57.260 So the very first thing I'm going to do 04:57.260 --> 05:01.535 is invoke one of those timeless, religious debates, this idea 05:01.535 --> 05:03.100 of spaces versus tabs. 05:03.100 --> 05:06.340 And yes, this slide does, in fact, have a space on one side 05:06.340 --> 05:07.340 and a tab on the other. 05:07.340 --> 05:11.492 You'll have to download the slides to figure out which one. 05:11.492 --> 05:13.700 But everybody has a different opinion on these things 05:13.700 --> 05:16.260 and there really is not one correct answer. 05:16.260 --> 05:18.560 Regardless of what a particular group may tell you, 05:18.560 --> 05:20.810 there really is not one particular answer, 05:20.810 --> 05:23.400 but teams will fight over this and developers will fight over 05:23.400 --> 05:25.720 this and it's one of the longest running 05:25.720 --> 05:27.200 battles in our development industry 05:27.200 --> 05:29.450 is this idea of spaces versus tabs. 05:29.450 --> 05:31.980 Another one that's slightly newer to JavaScript 05:31.980 --> 05:35.091 is this whole idea of semicolons versus no semicolons. 05:35.091 --> 05:37.590 And there's a strong contingent especially in the node world 05:37.590 --> 05:39.380 that will tell you semicolons are bad 05:39.380 --> 05:41.380 and you should not put them in because they make 05:41.380 --> 05:43.860 your code really ugly and it's too much the type to hit 05:43.860 --> 05:45.690 Shift-Semicolon or whatever. 05:45.690 --> 05:48.994 So we want to remove our semicolons from our code 05:48.994 --> 05:50.160 and I would be in that camp. 05:50.160 --> 05:52.243 Other people would say, no, no, no, we need those. 05:52.243 --> 05:54.570 So what if, and this is the question 05:54.570 --> 05:57.540 I want to pose, what if instead of us arguing 05:57.540 --> 05:59.560 about these sorts of things, instead 05:59.560 --> 06:03.150 of us raging these debates and forcing developers 06:03.150 --> 06:06.020 to believe differently than the rest of the team to conform, 06:06.020 --> 06:09.900 what if we could just agree to not have to agree. 06:09.900 --> 06:12.140 What if we didn't have to agree on these things. 06:12.140 --> 06:14.760 What if that's something that a tool could solve. 06:14.760 --> 06:16.970 So I am experimenting with-- and this is actually 06:16.970 --> 06:19.845 a much longer process than I thought because it turns out 06:19.845 --> 06:21.970 that we need a lot more information out of our code 06:21.970 --> 06:24.410 parsers, but I'm working on this tool called esre 06:24.410 --> 06:26.670 and this tool is designed specifically 06:26.670 --> 06:29.150 to take coding styles that you might 06:29.150 --> 06:31.050 say this is our standard for our team, 06:31.050 --> 06:32.610 but somebody else on the team they 06:32.610 --> 06:35.300 have a different set of standards for their styles. 06:35.300 --> 06:36.880 And rather than having a linting tool 06:36.880 --> 06:41.550 that's simply complained at you, this tool will just fix it. 06:41.550 --> 06:44.090 Isn't that amazing concept that rather than complaining 06:44.090 --> 06:47.110 at us as developers and putting a barrier to our workflow, 06:47.110 --> 06:49.020 we could create tools that just fix things. 06:49.020 --> 06:51.690 So it's a configurable two-way formatting tool. 06:51.690 --> 06:54.590 Instead of you having to change what you've done, 06:54.590 --> 06:57.240 the tool will automatically do it for you. 06:57.240 --> 07:00.240 But this is not just a talk about code styles, 07:00.240 --> 07:02.960 it actually goes much deeper. 07:02.960 --> 07:04.620 Are anybody aware in the audience 07:04.620 --> 07:05.690 the name of this movie? 07:05.690 --> 07:08.670 It's an old movie, obviously, the black and white days. 07:08.670 --> 07:10.410 It's called "12 Angry Men." 07:10.410 --> 07:12.875 And actually I love to think of this particular scene 07:12.875 --> 07:14.690 in this particular movie because I 07:14.690 --> 07:17.560 love to think of it as what happens inside of the TC39 07:17.560 --> 07:19.590 Committee meetings although, obviously, it's 07:19.590 --> 07:21.600 not that there's certainly much more inclusive. 07:21.600 --> 07:24.570 But I tweeted out this joke a while back 07:24.570 --> 07:27.720 and Allen Wirfs-Brock who's the maintainer of the ECMAscript 07:27.720 --> 07:29.710 spec, he wrote back to me and he said, 07:29.710 --> 07:31.420 I want to make sure that I claim that I'm 07:31.420 --> 07:33.240 the guy in the snazzy stripe suit. 07:33.240 --> 07:35.660 So that's Allen Wirfs-Brock in our picture. 07:35.660 --> 07:39.060 But it's a little bit opaque exactly how the process 07:39.060 --> 07:40.220 works for JavaScript. 07:40.220 --> 07:41.442 And let me be clear. 07:41.442 --> 07:42.900 I have an immense amount of respect 07:42.900 --> 07:45.191 for what they're doing on the standards committee, what 07:45.191 --> 07:47.520 they're doing with our language pushing it forward. 07:47.520 --> 07:49.820 There's a vast majority of things coming in JavaScript, 07:49.820 --> 07:53.460 the next version in ES6 that I think are absolutely fantastic. 07:53.460 --> 07:55.670 So I'm very excited about the future of the language 07:55.670 --> 07:57.794 and I'm very glad that those people are shepherding 07:57.794 --> 07:59.640 the future of the language, but it's also 07:59.640 --> 08:00.840 very opaque to many of us. 08:00.840 --> 08:03.570 And even though we can provide feedback on Twitter 08:03.570 --> 08:06.370 and we can even provide feedback through the discussion lists 08:06.370 --> 08:09.250 and things like that, there's a significant barrier there. 08:09.250 --> 08:11.680 I didn't feel even remotely competent to have 08:11.680 --> 08:14.520 those sorts of discussions until I spent the amount of time 08:14.520 --> 08:17.390 that I have obsessing about the JavaScript specification 08:17.390 --> 08:19.142 just like you get the right terminology. 08:19.142 --> 08:21.350 Because every time I would post an email to the list, 08:21.350 --> 08:23.058 I would get smacked down with, oh, you're 08:23.058 --> 08:24.860 using the wrong terms with things. 08:24.860 --> 08:28.010 And so it is not necessarily as easy for all of us 08:28.010 --> 08:30.970 to participate as we might ideally hope. 08:30.970 --> 08:33.770 And so part of this talk is to sort of liberate us 08:33.770 --> 08:36.659 from these processes and these standards and these tools. 08:36.659 --> 08:40.799 What if you could customize the JavaScript language itself 08:40.799 --> 08:42.460 to your own liking? 08:42.460 --> 08:44.366 What if instead of having to just 08:44.366 --> 08:45.990 take the compromises, which, of course, 08:45.990 --> 08:47.364 they do have to make compromises. 08:47.364 --> 08:50.362 They have to serve an enormous set of developers, 08:50.362 --> 08:52.570 an enormous audience with lots of different competing 08:52.570 --> 08:53.310 interests. 08:53.310 --> 08:55.726 But what if you didn't have to settle for that compromise. 08:55.726 --> 08:58.160 What if you could choose to customize this language? 08:58.160 --> 09:00.290 I go back to what I said at the beginning. 09:00.290 --> 09:02.500 Source code is not for the computer. 09:02.500 --> 09:04.490 Source code is for the developer. 09:04.490 --> 09:07.170 Your computer only cares about ones and zeroes 09:07.170 --> 09:08.740 and there's a nearly infinite number 09:08.740 --> 09:11.210 of programs that can produce the same sequence of ones 09:11.210 --> 09:12.120 and zeros. 09:12.120 --> 09:13.860 So your task as a developer is not 09:13.860 --> 09:17.320 to argue about spaces versus tabs, your job 09:17.320 --> 09:20.800 as a developer is to figure out the language and the tool set 09:20.800 --> 09:24.607 and the process that works most naturally for you, freeing you 09:24.607 --> 09:26.440 from all of those barriers so that you could 09:26.440 --> 09:28.340 write the best code possible. 09:28.340 --> 09:29.810 And that's a somewhat counterclaim 09:29.810 --> 09:32.632 because many people think the process standardization is 09:32.632 --> 09:33.840 the only way to move forward. 09:33.840 --> 09:35.420 We've heard talks that have suggested 09:35.420 --> 09:37.128 that we have to standardize on everything 09:37.128 --> 09:39.440 and there has to be a convention and a configuration 09:39.440 --> 09:41.280 for everything, but I'm pushing back on that 09:41.280 --> 09:43.560 and saying, perhaps that's optimizing 09:43.560 --> 09:46.870 for what I call a local maximum and it misses the big picture, 09:46.870 --> 09:48.680 the big picture that we as developers have 09:48.680 --> 09:52.192 individual likes and styles and things that we prefer. 09:52.192 --> 09:54.400 So I'll first start by talking about a project called 09:54.400 --> 09:55.760 sweet.js. 09:55.760 --> 09:58.650 And this was started independently a couple of years 09:58.650 --> 10:02.990 ago as a way to provide macros to the JavaScript language. 10:02.990 --> 10:04.720 And it caught on and it's actually 10:04.720 --> 10:07.830 gotten so much popularity that it's been adopted officially 10:07.830 --> 10:09.620 by the Mozilla family and they're 10:09.620 --> 10:12.600 shepherding this project and continuing to fund work 10:12.600 --> 10:15.470 on this project and there's a very, very strong chance 10:15.470 --> 10:19.110 that in a near coming version of language, perhaps ES7, maybe 10:19.110 --> 10:21.980 ES8, in that sort of time frame, we're 10:21.980 --> 10:23.560 going to see macros land a language 10:23.560 --> 10:25.320 and they're almost certainly going to land 10:25.320 --> 10:27.490 to look very similar to this. 10:27.490 --> 10:30.170 Now, what happened was a group of people said, 10:30.170 --> 10:33.020 let's research and experiment with a set of features 10:33.020 --> 10:35.900 that we want to add that are not standard yet. 10:35.900 --> 10:37.670 Let's figure those things out and that 10:37.670 --> 10:39.410 should sound familiar to you if you know 10:39.410 --> 10:41.250 anything about CoffeeScript. 10:41.250 --> 10:43.286 The same idea was, we want to write better code, 10:43.286 --> 10:45.660 code that we like to write, better code that works better 10:45.660 --> 10:47.970 with our brains, that smooths over the problems that 10:47.970 --> 10:50.710 prevent us from doing good things in JavaScript. 10:50.710 --> 10:52.770 So we'll write CoffeeScript. 10:52.770 --> 10:55.330 And CoffeeScript, although I don't personally like it, 10:55.330 --> 10:58.460 is a fantastic thing for our community. 10:58.460 --> 10:59.960 In fact, many of the greatest things 10:59.960 --> 11:03.740 are coming in ES6 came directly because of the experimentation 11:03.740 --> 11:05.400 that happened in CoffeeScript. 11:05.400 --> 11:07.860 Another example, to give props to the Microsoft world, 11:07.860 --> 11:10.220 TypeScript is another perfect example 11:10.220 --> 11:13.560 of a tool that's been created in such a way to experiment 11:13.560 --> 11:15.850 with a set of things that are not yet standard, 11:15.850 --> 11:17.844 but hopefully could be one day. 11:17.844 --> 11:20.260 And they're already on record as saying some of the things 11:20.260 --> 11:22.140 that TypeScript has experimented with 11:22.140 --> 11:24.639 are likely things that will make their way into the language 11:24.639 --> 11:25.980 in some way, shape, or form. 11:25.980 --> 11:27.880 So turning our attention to this sweet.js, 11:27.880 --> 11:29.919 let me just give you a very brief look 11:29.919 --> 11:31.460 at the sorts of things that you might 11:31.460 --> 11:32.543 be able to do with macros. 11:32.543 --> 11:34.590 If you know about macros in other languages, 11:34.590 --> 11:37.550 then this will be fairly familiar to you. 11:37.550 --> 11:40.010 So here's some ugly code that I'm 11:40.010 --> 11:42.220 doing to do a very common developer task, which 11:42.220 --> 11:45.822 is I have an x variable, a foo variable, and a bar variable 11:45.822 --> 11:47.030 and I need to swap those two. 11:47.030 --> 11:49.170 I need to swap an x and a y in a general sense. 11:49.170 --> 11:50.670 And we know that we're going to have 11:50.670 --> 11:53.210 to have some sort of temporary variable to do that, 11:53.210 --> 11:55.890 so you use syntactic tricks, which are coming. 11:55.890 --> 11:59.990 So swap is actually a very basic but useful example 11:59.990 --> 12:01.280 of how you can define a macro. 12:01.280 --> 12:03.310 So the beginning part is the definition 12:03.310 --> 12:05.750 of the macro from lines 1 through 9 and then down 12:05.750 --> 12:07.480 at the bottom, the important part, 12:07.480 --> 12:10.440 is that all we have to know is that we call this thing that 12:10.440 --> 12:12.960 looks like a function, but it's not really a function. 12:12.960 --> 12:15.729 It's a language-level construct that's been added as a macro. 12:15.729 --> 12:17.270 And there's all kinds of other tricks 12:17.270 --> 12:20.000 that you can pull to create new operators 12:20.000 --> 12:23.190 a new syntactic tricks to solve these sorts of problems. 12:23.190 --> 12:26.410 Another example, this one is even more common, 12:26.410 --> 12:28.150 at least in my code and maybe you've 12:28.150 --> 12:29.760 run into these sorts of problems. 12:29.760 --> 12:32.730 You have a nested object with several properties nested deep 12:32.730 --> 12:35.200 and you need to check for the third or fourth level deep, 12:35.200 --> 12:37.890 but you're going to have to check all levels of that 12:37.890 --> 12:40.557 because if you check the first level and it's not in there 12:40.557 --> 12:42.640 and you check the second level and it's not there, 12:42.640 --> 12:44.720 it can throw some sort of runtime error in your code. 12:44.720 --> 12:46.420 And that's annoying to some people that 12:46.420 --> 12:48.420 come from other languages, but this is something 12:48.420 --> 12:50.410 that we can fix with macros. 12:50.410 --> 12:53.220 So this is actually directly from their site 12:53.220 --> 12:56.060 and the syntax is a little complex, I'll completely admit, 12:56.060 --> 13:00.130 but the usage of this is that I can say nullity x.y.z 13:00.130 --> 13:02.860 and it will automatically transform internally 13:02.860 --> 13:07.720 that code to run x ampersand, ampersand x.y, and x.y.z. 13:07.720 --> 13:09.920 So it will do those tests in a safe way. 13:09.920 --> 13:12.580 So it gets all of those details that have been frustrating you 13:12.580 --> 13:14.330 about that particular part of the language 13:14.330 --> 13:15.780 and it shoves them away. 13:15.780 --> 13:17.400 It makes you more productive developer 13:17.400 --> 13:19.521 and I think that's actually a very positive thing 13:19.521 --> 13:21.020 for the future of the language and I 13:21.020 --> 13:23.860 think it's something that we can begin to use, not only to solve 13:23.860 --> 13:25.380 our problems, to be more pragmatic 13:25.380 --> 13:28.230 about our development, but also to experiment 13:28.230 --> 13:30.555 with the future versions of the language. 13:30.555 --> 13:31.180 Think about it. 13:31.180 --> 13:33.030 If we've only had two or three people come up 13:33.030 --> 13:35.120 on a language that has influenced JavaScript, what 13:35.120 --> 13:37.220 could we do if millions of developers 13:37.220 --> 13:40.036 were empowered to try out their own things in the language 13:40.036 --> 13:41.410 and come up with great ideas that 13:41.410 --> 13:44.390 can then influence the future. 13:44.390 --> 13:46.540 But it's more than just macro because macros 13:46.540 --> 13:50.520 are powerful and important, but they are sometimes limited. 13:50.520 --> 13:53.320 So I'm thinking about something even bigger than this. 13:53.320 --> 13:54.852 Let me start with an example. 13:54.852 --> 13:56.310 This is one of my favorite features 13:56.310 --> 13:59.960 coming to JavaScript in ES6, which is block scoping. 13:59.960 --> 14:01.520 This particular example, if you don't 14:01.520 --> 14:04.430 know too much about JavaScript, all you really need to know 14:04.430 --> 14:07.340 is that this variable a declaration there on line 2, 14:07.340 --> 14:08.860 it will automatically be available 14:08.860 --> 14:12.170 outside of the block, which is contrary to the way it works 14:12.170 --> 14:13.870 in many other languages, which is 14:13.870 --> 14:15.380 that it would be block scoped. 14:15.380 --> 14:17.600 In JavaScript, all the variables are 14:17.600 --> 14:20.150 said to be belonging to the function scope 14:20.150 --> 14:22.950 so it's said that they're hoisted to the function scope. 14:22.950 --> 14:24.936 And so this a variable out on line 6, 14:24.936 --> 14:26.560 it's available even though you probably 14:26.560 --> 14:28.700 intended as a developer for it to only 14:28.700 --> 14:31.060 be available inside the block and this 14:31.060 --> 14:33.070 has created untold numbers of bugs and programs 14:33.070 --> 14:34.970 where people accidentally access things. 14:34.970 --> 14:37.870 So block scoping is an important and powerful technique, 14:37.870 --> 14:41.110 but unfortunately, it's just now landing in the language. 14:41.110 --> 14:44.500 The good news is that we're getting a let keyword as of ES6 14:44.500 --> 14:46.540 and that will create a variable declaration that 14:46.540 --> 14:48.010 will be block scoped. 14:48.010 --> 14:51.032 So this new let keyword, it's a big win for ES6. 14:51.032 --> 14:53.490 And it's going to allow us to enforce the things that we've 14:53.490 --> 14:55.070 been stylistically doing. 14:55.070 --> 14:58.370 For example, any time you've done for var i equals, 14:58.370 --> 15:01.065 when you do an i declaration inside of your for loop, 15:01.065 --> 15:04.180 you're signaling to yourself and others, your future self 15:04.180 --> 15:06.930 and your other team members that you attend i to only 15:06.930 --> 15:10.490 be used for loop, but it doesn't belong only to the for loop 15:10.490 --> 15:13.300 if use the var and it does if you use the let keyword. 15:13.300 --> 15:16.120 In fact, it solves many troubling issues about closures 15:16.120 --> 15:16.670 and so forth. 15:16.670 --> 15:18.870 So block scoping is a huge win for the language. 15:18.870 --> 15:20.290 I'm a big fan of it. 15:20.290 --> 15:21.957 Just as a side, by the way, some people 15:21.957 --> 15:23.540 are out there saying that you're going 15:23.540 --> 15:26.760 to replace all vars with let, so let is the new var. 15:26.760 --> 15:28.450 That's incredibly stupid advice. 15:28.450 --> 15:29.630 Please don't follow that. 15:29.630 --> 15:32.330 Do not just do a global find a replace on your code 15:32.330 --> 15:34.420 and write all new vars with lets. 15:34.420 --> 15:36.340 They're going to be both useful as far 15:36.340 --> 15:37.590 as I'm concerned in your code. 15:37.590 --> 15:39.256 You're going to use some vars and you're 15:39.256 --> 15:40.940 going to use some lets, but I encourage 15:40.940 --> 15:42.481 you to read up on some of that and it 15:42.481 --> 15:45.480 would be good if somebody had written a book about scoping. 15:45.480 --> 15:46.580 So let's move on. 15:46.580 --> 15:48.980 There are some problems with block scoping though. 15:48.980 --> 15:50.780 In particular, with this particular form 15:50.780 --> 15:52.590 of block scoping, this is what I would 15:52.590 --> 15:54.730 call the implicit let declaration 15:54.730 --> 15:58.390 and essentially what it does is it hijacks an existing block. 15:58.390 --> 16:00.400 There's a block there that's an if statement 16:00.400 --> 16:03.680 and it's hijacking it to give it some block scoping. 16:03.680 --> 16:06.617 So let's look at slightly more realistic-- obviously, this 16:06.617 --> 16:08.450 is still stupid code, but it's slightly more 16:08.450 --> 16:11.090 realistic because it has more lines of code in it. 16:11.090 --> 16:12.956 And it's actually going to show what 16:12.956 --> 16:14.330 I think is likely going to happen 16:14.330 --> 16:15.710 with let declarations is that they're going 16:15.710 --> 16:16.876 to get sprinkled throughout. 16:16.876 --> 16:20.250 So you see on line 2, you see a let declaration, on line 4, 16:20.250 --> 16:21.430 you see another one. 16:21.430 --> 16:23.763 And you're just going to subtly not realize until you've 16:23.763 --> 16:26.450 been bitten by this enough times that let declarations don't 16:26.450 --> 16:27.480 work quite like vars. 16:27.480 --> 16:29.640 They don't hoist to the top of the block, 16:29.640 --> 16:32.362 so if you were to try to use a before line 4, 16:32.362 --> 16:34.820 you're going to get breakage and there's some weird things. 16:34.820 --> 16:37.230 So it creates a lot of mental tax here. 16:37.230 --> 16:38.950 And it's more than just that. 16:38.950 --> 16:40.660 There's a refactoring tax. 16:40.660 --> 16:43.030 So prior to this when we had declarations, 16:43.030 --> 16:45.372 no matter where we put them, they always belonged 16:45.372 --> 16:46.830 to the entire function scope, which 16:46.830 --> 16:49.130 meant we could move if statements all around 16:49.130 --> 16:50.710 and it wasn't a big deal. 16:50.710 --> 16:54.250 We could sort of play loose and fast with the rules of scoping. 16:54.250 --> 16:55.390 Now, that wasn't good code. 16:55.390 --> 16:57.660 I'm not suggesting that that was a good thing, 16:57.660 --> 17:01.789 but this sort of code is a reality in our industry. 17:01.789 --> 17:03.830 I've written this code, you've written this code, 17:03.830 --> 17:04.746 everybody's done this. 17:04.746 --> 17:06.457 And if you replace them all with lets 17:06.457 --> 17:08.290 and then you start willy-nilly saying, well, 17:08.290 --> 17:09.890 I'll just take that if statement and I'll move it 17:09.890 --> 17:11.510 outside of the block, you're going 17:11.510 --> 17:13.858 to get refactoring hazards because you're 17:13.858 --> 17:15.650 going have to remember what needs to moved. 17:15.650 --> 17:18.560 So you do need to be careful with the let statement 17:18.560 --> 17:21.348 and especially in its implicit form. 17:21.348 --> 17:24.810 I would prefer an explicit form of block scoping 17:24.810 --> 17:27.310 and it turns out there is a form of the let declaration that 17:27.310 --> 17:30.080 was pioneered over a decade ago in Firefox 17:30.080 --> 17:32.080 and it's called the let block or otherwise known 17:32.080 --> 17:33.320 as the let statement. 17:33.320 --> 17:35.170 You'll notice there line 3, I'm declaring 17:35.170 --> 17:39.090 an explicit block, a let a and I can do multiple variables 17:39.090 --> 17:39.730 in there. 17:39.730 --> 17:41.580 That's an explicit block that does nothing 17:41.580 --> 17:43.570 except create scope. 17:43.570 --> 17:45.872 Explicit is usually preferred by developers 17:45.872 --> 17:48.080 and this is one of those cases where I think explicit 17:48.080 --> 17:49.800 is better than implicit. 17:49.800 --> 17:51.440 Some people hate the extra indentation, 17:51.440 --> 17:53.980 but I think that it reduces the mental tax, 17:53.980 --> 17:56.470 it reduces the refactoring hazard. 17:56.470 --> 17:59.800 But there's a problem because this syntax was unfortunately 17:59.800 --> 18:01.910 rejected by ES6. 18:01.910 --> 18:06.892 It is, in my opinion, a superior syntax, but it was rejected. 18:06.892 --> 18:07.600 So what do we do? 18:07.600 --> 18:09.683 Do we just say, well, I guess we're just relegated 18:09.683 --> 18:11.450 to writing crappier code. 18:11.450 --> 18:13.674 That's sort of the inspiration for this talk 18:13.674 --> 18:15.590 is that particular example and we'll come back 18:15.590 --> 18:16.860 to that in just a minute. 18:16.860 --> 18:19.410 But let's take a step back and ask what exactly is it 18:19.410 --> 18:20.730 that I'm suggesting. 18:20.730 --> 18:23.730 Am I suggesting democracy or anarchy? 18:23.730 --> 18:26.720 The answer is, yes, I'm suggesting all of these things. 18:26.720 --> 18:28.250 I'm suggesting that it's OK for you 18:28.250 --> 18:30.340 to take matters into your own hands. 18:30.340 --> 18:32.990 It's absolutely OK for you to decide 18:32.990 --> 18:35.430 what is a tool set that's going to work better for me. 18:35.430 --> 18:37.859 How is it going to make me more productive as a developer. 18:37.859 --> 18:39.400 Now, I know in the back of your minds 18:39.400 --> 18:41.400 there's going to be a question about collaboration 18:41.400 --> 18:42.941 and I promise we'll get back to that, 18:42.941 --> 18:45.090 so hold on to that question. 18:45.090 --> 18:47.654 Now, this could be the official sort of avatar photo for me 18:47.654 --> 18:49.070 at this point because I'm starting 18:49.070 --> 18:50.996 to look like kind of a crazy guy telling you 18:50.996 --> 18:53.370 that you should just be writing your own JavaScript code. 18:53.370 --> 18:55.250 It's actually the official motto for a language 18:55.250 --> 18:56.916 that I was going to write that was going 18:56.916 --> 18:58.900 to be called FoilScript and then I 18:58.900 --> 19:01.470 realized I don't need to write a different language, 19:01.470 --> 19:03.550 I just did to take all of these things 19:03.550 --> 19:05.905 that I don't like that slowed me down about JavaScript 19:05.905 --> 19:07.370 and I need to fix them. 19:07.370 --> 19:10.370 I need to create a tool or a set of tools to fix them, 19:10.370 --> 19:13.290 so FoilScript is essentially my unofficial collection 19:13.290 --> 19:15.930 of complaints about the language. 19:15.930 --> 19:18.800 So you might be asking yourself he's basically 19:18.800 --> 19:22.300 talking about non-standard or even partial JavaScript 19:22.300 --> 19:25.400 and more importantly, how is it that I'm going to even possibly 19:25.400 --> 19:26.040 parse that. 19:26.040 --> 19:28.280 If you know anything about how JavaScript works, 19:28.280 --> 19:30.350 we have standard parsers, but what do 19:30.350 --> 19:32.020 they do with non-standard code? 19:32.020 --> 19:34.226 What happens if you made up your own syntax, 19:34.226 --> 19:36.350 would a standardized parser be able to handle that? 19:36.350 --> 19:38.210 And in many cases, unfortunately, the answer 19:38.210 --> 19:38.710 is no. 19:38.710 --> 19:42.320 Sometimes there are loose parser modes, but in many cases, 19:42.320 --> 19:44.902 our current set of tools would fall down. 19:44.902 --> 19:46.360 So one of the things when I started 19:46.360 --> 19:48.850 to write these sorts of tools is I said, well, we 19:48.850 --> 19:51.470 need to solve that problem and I looked at the JavaScript 19:51.470 --> 19:53.590 language and I looked at this idea of how 19:53.590 --> 19:54.770 do you parse through code. 19:54.770 --> 19:57.090 And the initial reaction might be say, well, 19:57.090 --> 19:58.570 let's use regular expressions. 19:58.570 --> 20:01.880 Unfortunately, JavaScript is not a regular language, 20:01.880 --> 20:03.442 it's not a regular grammar, so you 20:03.442 --> 20:04.900 can't use regular expressions on it 20:04.900 --> 20:07.770 because there's stateful things like string literals 20:07.770 --> 20:11.440 and comments and regular expression literals themselves. 20:11.440 --> 20:14.130 Those are what I call the difficult literals. 20:14.130 --> 20:16.190 If we had a tool that could sort of figure out 20:16.190 --> 20:19.290 where those were in our code and pre-identify them 20:19.290 --> 20:22.890 and pull them out, the language becomes significantly easier 20:22.890 --> 20:25.620 to reason about even with regular expressions. 20:25.620 --> 20:27.780 So I wrote a tool called Literalizer, 20:27.780 --> 20:30.800 which literally takes your code and goes through 20:30.800 --> 20:34.180 an instead of using a parser, it uses a set of heuristics 20:34.180 --> 20:35.910 derived from the JavaScript grammar 20:35.910 --> 20:39.920 to figure out where those strings and regular expressions 20:39.920 --> 20:42.190 and comments are and then simply pulls them out. 20:42.190 --> 20:44.190 It pre-identifies them leaving you 20:44.190 --> 20:46.310 with a much simpler set of strings of code 20:46.310 --> 20:48.440 that you could run regular expressions against 20:48.440 --> 20:51.150 to say find various different things you want to do. 20:51.150 --> 20:53.820 And I'm using that particular tool in a tool 20:53.820 --> 20:55.600 that I'll talk about in just a moment. 20:55.600 --> 20:57.250 So that's one step. 20:57.250 --> 20:59.570 That's the first step towards building 20:59.570 --> 21:01.870 these sorts of crazy tools is that we need help 21:01.870 --> 21:04.164 and this tool might help. 21:04.164 --> 21:05.580 Let's go back to our block scoping 21:05.580 --> 21:07.530 example for just a moment. 21:07.530 --> 21:09.410 This particular block, I would prefer 21:09.410 --> 21:12.464 to write code like this because it's more explicit, 21:12.464 --> 21:14.130 but it is it going to run in the browser 21:14.130 --> 21:15.419 because it's not ES6 standard. 21:15.419 --> 21:17.460 Maybe they'll come back and standardize it later, 21:17.460 --> 21:19.240 but right now it's not standard. 21:19.240 --> 21:20.670 So what am I going to do? 21:20.670 --> 21:23.520 I'm going to write a tool I wrote a tool called let-er that 21:23.520 --> 21:26.110 takes that particular code and by default, it 21:26.110 --> 21:29.200 will now transpile it to the code you see there. 21:29.200 --> 21:31.390 You see, all I did was just move the characters 21:31.390 --> 21:32.223 around a little bit. 21:32.223 --> 21:34.200 It's actually not a significant change, 21:34.200 --> 21:38.240 but the second snippet is actually ES6 standard code. 21:38.240 --> 21:40.110 So it's a very simple transpilation 21:40.110 --> 21:42.200 of our code from something nonstandard 21:42.200 --> 21:43.682 to something standard. 21:43.682 --> 21:45.640 And it allows meet our author code in something 21:45.640 --> 21:48.390 that I think is more reasonable, it has less mental tax, 21:48.390 --> 21:49.680 and yet still target my code. 21:49.680 --> 21:52.100 So we're not even talking about significant rewrites 21:52.100 --> 21:53.770 like something like CoffeeScript. 21:53.770 --> 21:56.020 It can be very simple things like this. 21:56.020 --> 21:58.352 Now that's the ES6 mode and my preferred option 21:58.352 --> 22:00.560 would be that you would use that and then, of course, 22:00.560 --> 22:02.642 use the rest of ES6 syntax. 22:02.642 --> 22:04.600 You're going to use some generalized transpiler 22:04.600 --> 22:07.180 like Google Traceur or some of the others out there 22:07.180 --> 22:08.924 and you're going to target ES5 code 22:08.924 --> 22:11.090 and they've got a variety of ways that they do that. 22:11.090 --> 22:12.680 I'll show you Traceur in a moment. 22:12.680 --> 22:14.971 But let's say you want to use let-er totally standalone 22:14.971 --> 22:17.470 and you're not going to do anything except block scoping. 22:17.470 --> 22:22.350 There is an ES3 mode and it produces this crazy hacky code, 22:22.350 --> 22:27.250 which is forcing a tri catch and the catch block is actually 22:27.250 --> 22:28.010 block scope. 22:28.010 --> 22:30.300 That's the way it was defined way back in ES3. 22:30.300 --> 22:32.716 So yeah, we don't want to write pack hacky code like that. 22:32.716 --> 22:34.214 It's not a great solution. 22:34.214 --> 22:36.380 Use one of those other tools if you prefer, but this 22:36.380 --> 22:39.000 is a standalone way that you could start targeting block 22:39.000 --> 22:42.640 scoping code in all of the browsers today. 22:42.640 --> 22:45.260 Even if you don't like my particular form, 22:45.260 --> 22:47.890 I would still implore you to write code more like this. 22:47.890 --> 22:49.220 Create explicit blocks. 22:49.220 --> 22:51.350 This is totally valid for you to author. 22:51.350 --> 22:52.330 It's your choice. 22:52.330 --> 22:55.390 Do you want to do implicit block scoping or explicit block 22:55.390 --> 22:56.025 scoping. 22:56.025 --> 22:57.900 So I would encourage you to at least consider 22:57.900 --> 22:59.626 writing code like that. 22:59.626 --> 23:00.750 Here's Traceur, by the way. 23:00.750 --> 23:02.630 They have an online demo that shows things 23:02.630 --> 23:04.588 and I want to show you how they're particularly 23:04.588 --> 23:07.060 doing their cross compilation. 23:07.060 --> 23:10.255 It depends on your level of choice, 23:10.255 --> 23:12.130 whether you think this is more or less hacky. 23:12.130 --> 23:13.970 But they take the code on the left 23:13.970 --> 23:16.550 and then they turn it into the code here on the right. 23:16.550 --> 23:20.601 So they're doing what's called hygienic variable renaming. 23:20.601 --> 23:22.100 It's a fancy way of saying-- they're 23:22.100 --> 23:25.904 coming up with unique variable names to rename things to. 23:25.904 --> 23:27.570 So they're still using vars, but they're 23:27.570 --> 23:29.530 coming up with unique names that's 23:29.530 --> 23:32.009 kind of behave like they were block scoped. 23:32.009 --> 23:34.300 It's another one of the hacks and tricks and techniques 23:34.300 --> 23:36.091 and if you like that one better, of course, 23:36.091 --> 23:38.250 Traceur is a better way to go. 23:38.250 --> 23:40.040 Traceur, up until a couple months ago, 23:40.040 --> 23:41.280 was using the try/catch hack. 23:41.280 --> 23:45.037 So there's various different hacks to go about this. 23:45.037 --> 23:46.870 Let's look at some other examples, ones that 23:46.870 --> 23:48.150 may not be quite so well known. 23:48.150 --> 23:50.816 These are ones that don't really have a standards track for them 23:50.816 --> 23:53.430 at all or aren't really rooted in any particular reality 23:53.430 --> 23:56.070 except my own, but I'll just share them as examples. 23:56.070 --> 23:57.810 You don't have to really even understand 23:57.810 --> 24:00.600 exactly what's going on, but in this particular example, 24:00.600 --> 24:02.490 to express what I'm really saying, 24:02.490 --> 24:05.750 what I'm saying with line 2 here is, I'm saying the string foo, 24:05.750 --> 24:08.006 the key foo is not in bar. 24:08.006 --> 24:09.880 But you notice how I grammatically said that. 24:09.880 --> 24:12.950 I said not in, but unfortunately, syntactically we 24:12.950 --> 24:14.920 have to reverse our brains a little bit 24:14.920 --> 24:19.990 and we have to say, not the case that foo is in bar. 24:19.990 --> 24:22.540 We don't have a not in operator. 24:22.540 --> 24:24.670 Except why don't we have a not in operator? 24:24.670 --> 24:26.630 Why don't we have a not instance of operator. 24:26.630 --> 24:28.046 In fact, why don't we have and not 24:28.046 --> 24:30.030 and operator and a not or operator, 24:30.030 --> 24:32.030 because that would make a little bit more sense. 24:32.030 --> 24:34.030 It would create less mental barrier 24:34.030 --> 24:36.787 to be expressing things the way my brain is planning them. 24:36.787 --> 24:38.870 Instead of having to force me to go through hoops, 24:38.870 --> 24:41.890 I could write code that made more sense. 24:41.890 --> 24:45.140 So why couldn't we just put the negate statement right 24:45.140 --> 24:47.180 in front of the in operator? 24:47.180 --> 24:48.740 This is a very easy transform. 24:48.740 --> 24:51.500 I've already written a proof of concept of this particular tool 24:51.500 --> 24:54.824 to take in infix operators and move them around like that. 24:54.824 --> 24:56.240 So I'd rather write code like this 24:56.240 --> 24:57.406 because it makes more sense. 24:57.406 --> 24:59.340 I'm saying not in, and not instance of, 24:59.340 --> 25:03.090 and not and because that's what my brain actually means. 25:03.090 --> 25:05.730 I think not only does it allow me to write better code, if we 25:05.730 --> 25:07.800 trained ourselves to read that, we would see 25:07.800 --> 25:09.487 that that code reads easier. 25:09.487 --> 25:11.570 We don't have to jump through hoops in our brains. 25:14.340 --> 25:16.330 Another example. 25:16.330 --> 25:19.710 Conditional else clauses on ternaries, 25:19.710 --> 25:21.870 the ternary operator that everybody probably knows, 25:21.870 --> 25:24.040 the question mark colon operator is sometimes 25:24.040 --> 25:25.714 called the conditional operator. 25:25.714 --> 25:27.630 I don't know about your code, but many times I 25:27.630 --> 25:29.800 find myself writing in these patterns 25:29.800 --> 25:32.630 while I end up having this basically optional thing 25:32.630 --> 25:34.690 over here on the right whereas, I'm 25:34.690 --> 25:38.129 trying to set something if a condition exists and I can't 25:38.129 --> 25:40.170 use the OR operator here because they're actually 25:40.170 --> 25:41.889 different between condition value. 25:41.889 --> 25:44.180 But I'm trying to set something, if a condition exists, 25:44.180 --> 25:46.290 and otherwise, I just want to leave it undefined. 25:46.290 --> 25:47.950 It's not set yet. 25:47.950 --> 25:50.390 This is a pattern I find very common, especially 25:50.390 --> 25:52.230 in my variable parameters. 25:52.230 --> 25:55.890 This is a more robust form of the OR operator, 25:55.890 --> 25:59.450 NULL-coalescing operator, if you've heard that terminology. 25:59.450 --> 26:01.700 But I don't like writing colon undefined over and over 26:01.700 --> 26:04.010 and over again and essentially, why couldn't I 26:04.010 --> 26:05.660 make that optional? 26:05.660 --> 26:07.830 I proposed this a while back and they said, 26:07.830 --> 26:10.330 they hummed and hawed and said, well, I'm 26:10.330 --> 26:11.380 not sure if we can do it. 26:11.380 --> 26:13.820 So I wrote a tool that can do this. 26:13.820 --> 26:15.840 It's just a localized thing that I use myself, 26:15.840 --> 26:19.090 but it allows you to skip them if they're optional. 26:19.090 --> 26:21.380 And the tool will simply go in and insert them 26:21.380 --> 26:23.380 if you have left them off. 26:23.380 --> 26:26.280 And no, there's no difference in terms of operator precedence, 26:26.280 --> 26:30.920 it's exactly the same rules as would apply without it. 26:30.920 --> 26:34.290 This is just a small little taste of the sorts of things 26:34.290 --> 26:36.040 that I find frustrating about the language 26:36.040 --> 26:37.440 that I'd like to fix. 26:37.440 --> 26:39.540 I'm sure you have your own list and I'm not 26:39.540 --> 26:41.790 suggesting that every single problem could possibly 26:41.790 --> 26:44.090 be fixed this way, but I think a lot of them could. 26:44.090 --> 26:46.170 A lot of the problems that we've been frustrated 26:46.170 --> 26:47.680 with that have been holding us back, 26:47.680 --> 26:50.600 we can address them using better tools. 26:50.600 --> 26:52.830 And I hope to inspire more people to write the tools, 26:52.830 --> 26:55.910 but I also hope to inspire more people to experiment 26:55.910 --> 26:57.924 with what would be better coding for them 26:57.924 --> 26:59.340 because that's input that would be 26:59.340 --> 27:02.590 valuable for the future of the language. 27:02.590 --> 27:05.190 So these optional clauses would actually be kind of nice, 27:05.190 --> 27:07.160 at least for my coding. 27:07.160 --> 27:10.260 Another example, promiscuous this binding. 27:10.260 --> 27:12.220 If you've ever struggled with the this keyword, 27:12.220 --> 27:13.840 it does not mean self. 27:13.840 --> 27:14.710 Trust me. 27:14.710 --> 27:15.650 It doesn't mean self. 27:15.650 --> 27:17.870 There is a pre-defined set of rules about it. 27:17.870 --> 27:20.570 It would be nice if somebody would write a book specifically 27:20.570 --> 27:22.350 about how the this keyword works. 27:22.350 --> 27:23.950 But it's a very frustrating topic 27:23.950 --> 27:25.700 because developers struggle to understand 27:25.700 --> 27:27.300 exactly how it works. 27:27.300 --> 27:29.560 There's a related topic to promiscuous this binding, 27:29.560 --> 27:31.069 which is the hard binding and that's 27:31.069 --> 27:33.110 what you often are faced with when you're passing 27:33.110 --> 27:34.920 around functions into event handlers 27:34.920 --> 27:38.070 and they're losing their this binding and so forth. 27:38.070 --> 27:39.940 And then there's another much lesser known, 27:39.940 --> 27:42.090 but actually, I find this very useful in my code 27:42.090 --> 27:44.140 and I call it soft this binding. 27:44.140 --> 27:46.470 There's actually a proposal for a future version 27:46.470 --> 27:48.636 of the language that they might try to address this, 27:48.636 --> 27:51.330 but I don't like their proposal and it hasn't had any support, 27:51.330 --> 27:53.290 so it's probably not going to happen anyway. 27:53.290 --> 27:56.294 But soft this binding simply provides a different default. 27:56.294 --> 27:58.460 Instead of defaulting to the window or global, which 27:58.460 --> 28:00.460 is never what we want, it allows you 28:00.460 --> 28:03.546 to find your own backup default but still overridable. 28:03.546 --> 28:05.566 You can actually writes soft binding like this 28:05.566 --> 28:07.440 and I know that code might look overwhelming. 28:07.440 --> 28:09.230 You don't really need to understand the implementation 28:09.230 --> 28:09.730 details. 28:09.730 --> 28:11.710 If you want to, you can find my code online. 28:11.710 --> 28:13.360 But the important part here is I could 28:13.360 --> 28:16.840 call soft bind on a function and provide an alternate back 28:16.840 --> 28:19.110 up which is still overridable. 28:19.110 --> 28:20.930 It's like the best of hard binding 28:20.930 --> 28:24.120 but also it's overridable, so it gives you more flexibility 28:24.120 --> 28:27.920 but still it removes that ugly back fall or default 28:27.920 --> 28:30.570 that the global object is. 28:30.570 --> 28:32.970 This is yet another thing that I can solve with code 28:32.970 --> 28:37.630 but it's ugly and I would like to solve this with syntax. 28:37.630 --> 28:39.540 So I've got a proof of concept that we 28:39.540 --> 28:42.040 can do something like use the pound operator 28:42.040 --> 28:44.710 like you see here to provide a soft binding 28:44.710 --> 28:47.016 hint for a function. 28:47.016 --> 28:49.420 It does exactly the same thing as the previous code, 28:49.420 --> 28:51.100 but in my code, I don't have to worry 28:51.100 --> 28:53.650 about all the complexities of writing that soft bind and what 28:53.650 --> 28:54.441 am I passing in it. 28:54.441 --> 28:56.390 It's a syntactic change, slightly 28:56.390 --> 28:58.450 more intrusive, I guess, than some of the others, 28:58.450 --> 29:00.520 but it's proof that there are tangible things 29:00.520 --> 29:02.020 that we could fix about the language 29:02.020 --> 29:05.480 if we chose to experiment with tools. 29:05.480 --> 29:07.697 And finally, conditional catch clauses. 29:07.697 --> 29:09.280 This is something that other languages 29:09.280 --> 29:10.550 have had for a long time. 29:10.550 --> 29:12.310 In fact, this is something that Firefox 29:12.310 --> 29:15.252 has had for like over a decade, but that hasn't had a standards 29:15.252 --> 29:17.210 track and I've been wishing that they would get 29:17.210 --> 29:18.260 this on the standards track. 29:18.260 --> 29:20.509 You have this example where you want to catch a clause 29:20.509 --> 29:23.130 but only conditionally, only if it's a certain type of error, 29:23.130 --> 29:25.885 otherwise, you want to let it just continue to propagate out. 29:25.885 --> 29:27.810 And that's actually a very important concept 29:27.810 --> 29:30.130 in certain coding patterns. 29:30.130 --> 29:32.710 The problem is that we have to do this really ugly re-throw 29:32.710 --> 29:34.880 thing and in some browsers, that actually 29:34.880 --> 29:36.590 can change the way the stack works 29:36.590 --> 29:39.984 and what the line numbers are, so that sucks. 29:39.984 --> 29:41.900 This is not a great solution, but it's the way 29:41.900 --> 29:43.277 that some people do this. 29:43.277 --> 29:44.860 But even if you were going to do this, 29:44.860 --> 29:46.526 I don't want to write this kind of code. 29:46.526 --> 29:49.240 I don't want to have to write that else throw error crap, 29:49.240 --> 29:52.080 so it actually is yet another thing that we can fix. 29:52.080 --> 29:54.520 And I'm using, again, exactly the same syntax 29:54.520 --> 29:56.366 that was already pioneered with Firefox. 29:56.366 --> 29:58.740 You simply put the if statement right inside of the catch 29:58.740 --> 29:59.710 clause. 29:59.710 --> 30:02.560 If error, error if only the error 30:02.560 --> 30:04.550 is an instance of type error or error 30:04.550 --> 30:06.270 if it's an instance of reference error. 30:06.270 --> 30:08.580 And if it doesn't match, it doesn't get caught, 30:08.580 --> 30:10.990 it just keeps propagating. 30:10.990 --> 30:13.580 This is a simple syntactic change 30:13.580 --> 30:15.820 and we get the benefits of not having to worry 30:15.820 --> 30:18.630 about all those details. 30:18.630 --> 30:21.180 So basically what I'm saying is JavaScript your way. 30:21.180 --> 30:22.460 Have it your way. 30:22.460 --> 30:24.420 Have it the way that works best for your brain 30:24.420 --> 30:26.720 and let tools do the heavy lifting for you 30:26.720 --> 30:28.560 instead of always forcibly having to change 30:28.560 --> 30:29.820 the way your brains think. 30:29.820 --> 30:31.200 Sometimes that's unavoidable. 30:31.200 --> 30:33.261 Sometimes you do have to learn things though. 30:33.261 --> 30:35.760 Don't hear me to say that this is an excuse for not learning 30:35.760 --> 30:36.900 JavaScript. 30:36.900 --> 30:38.870 But once you learn JavaScript and you realize 30:38.870 --> 30:41.660 that there are limitations, don't feel like you're stuck. 30:41.660 --> 30:43.580 Don't feel like the only option is to just go 30:43.580 --> 30:45.320 to an entirely new language. 30:45.320 --> 30:48.374 Sometimes you can just change what you've already got. 30:48.374 --> 30:50.540 So now back to that question that I know many of you 30:50.540 --> 30:52.930 have been having about team collaboration. 30:52.930 --> 30:54.840 What on Earth could I possibly do 30:54.840 --> 30:56.626 to collaborate with other team members 30:56.626 --> 30:58.750 if we had this anarchy that everybody was coming up 30:58.750 --> 30:59.780 with their own syntax? 30:59.780 --> 31:01.760 How could we possibly do that? 31:01.760 --> 31:04.390 And it's a very good and important question. 31:04.390 --> 31:06.395 My answer to that question is under researched, 31:06.395 --> 31:07.770 but my answer to that question is 31:07.770 --> 31:09.890 what I call defining these things in terms 31:09.890 --> 31:11.907 of inversable transforms. 31:11.907 --> 31:13.740 I just made up a term to sort of make myself 31:13.740 --> 31:14.864 sound a little bit smarter. 31:14.864 --> 31:16.442 I don't even know if that's accurate. 31:16.442 --> 31:17.900 But essentially, what I'm saying is 31:17.900 --> 31:20.000 that all those things that I showed you 31:20.000 --> 31:21.370 have two-way bindings. 31:21.370 --> 31:24.780 You can go in either direction fairly straightforwardly. 31:24.780 --> 31:27.310 So a tool could be set up that allows 31:27.310 --> 31:31.830 you to have a rule set for what is checked into the git-repo 31:31.830 --> 31:34.740 and a rule set for what's shown in your code editor 31:34.740 --> 31:37.587 and let the tool handle going in both directions. 31:37.587 --> 31:39.170 When you check out from the code base, 31:39.170 --> 31:40.586 it makes the code look the way you 31:40.586 --> 31:44.250 want it to look including your spaces or tabs or semicolons 31:44.250 --> 31:46.042 or whatever and all these other transforms. 31:46.042 --> 31:48.541 And then when you're done and you're ready to check back in, 31:48.541 --> 31:50.930 the tool just does it in the reverse direction. 31:50.930 --> 31:52.540 So what's agreed upon is the rule 31:52.540 --> 31:55.725 set that goes into the repo and whatever the developer has is 31:55.725 --> 31:57.100 what they get to pick themselves. 31:57.100 --> 31:59.170 And really this is actually trying 31:59.170 --> 32:00.920 to solve the problem that CoffeeScript 32:00.920 --> 32:04.200 did because CoffeeScript went so far with its changes 32:04.200 --> 32:06.060 that essentially this was an all or nothing. 32:06.060 --> 32:08.590 It was very difficult for members of the same team 32:08.590 --> 32:10.420 to write both CoffeeScript and JavaScript. 32:10.420 --> 32:14.367 So it's kind of like all CoffeeScript or none. 32:14.367 --> 32:16.200 But I'm hoping that there's a set of changes 32:16.200 --> 32:18.830 that we can do to improve the language that we can still 32:18.830 --> 32:21.280 collaborate on, that can still have check ins. 32:21.280 --> 32:23.330 And really, to be honest with you, 32:23.330 --> 32:25.550 the weak point here is pure coding. 32:25.550 --> 32:27.044 If I have a radically different way 32:27.044 --> 32:28.710 that my code looks on my screen and then 32:28.710 --> 32:30.668 one of the other developers comes over and sits 32:30.668 --> 32:33.182 at my screen, it might look different to him. 32:33.182 --> 32:35.140 But then again I don't do a lot of pure coding, 32:35.140 --> 32:37.620 so maybe that's why that isn't such a big deal to me, 32:37.620 --> 32:40.380 but I still think there's a way that even if we decided 32:40.380 --> 32:43.960 as a team these are the styles and we didn't customize 32:43.960 --> 32:46.735 the styles to individuals, but we customize it to the team, 32:46.735 --> 32:48.235 you could solve even those problems. 32:51.030 --> 32:53.140 Back to that example. 32:53.140 --> 32:56.390 Just to prove that this is inversable, if you look here, 32:56.390 --> 32:58.350 the difference is simply whether or not 32:58.350 --> 32:59.830 the colon undefined is there. 32:59.830 --> 33:02.084 It's easy to look for that to parse 33:02.084 --> 33:03.750 through some basic grammatical structure 33:03.750 --> 33:06.590 and understand if it's there or not and if it's not there, 33:06.590 --> 33:08.660 put it there and if it is there, take it out. 33:08.660 --> 33:10.520 That's all it takes. 33:10.520 --> 33:11.850 So most of these rules. 33:11.850 --> 33:13.808 Now, that's not going to let you do everything. 33:13.808 --> 33:16.050 Not every I think and be defined inversably. 33:16.050 --> 33:18.490 So there might be some changes which are destructive 33:18.490 --> 33:19.560 or there might be some changes that 33:19.560 --> 33:21.330 are a little bit more difficult to build a tool around, 33:21.330 --> 33:23.040 but there's a lot of low-hanging fruit 33:23.040 --> 33:27.250 that we can fix if we just open up our brains to that. 33:27.250 --> 33:29.160 So this is an open area of research. 33:29.160 --> 33:31.540 I don't have any solid, perfect answers that 33:31.540 --> 33:33.580 are production ready yet, but I'm 33:33.580 --> 33:36.862 hoping to encourage and inspire people to go further with that. 33:36.862 --> 33:39.070 Now, let me talk about some tools that already exist. 33:39.070 --> 33:40.630 These are concrete tools that already 33:40.630 --> 33:44.020 exist that we can use to help us along the way. 33:44.020 --> 33:46.970 Parsing JavaScript is a non-trivial task. 33:46.970 --> 33:49.170 I happen to like writing compilers and I'm a geek 33:49.170 --> 33:50.990 and I'm weird like that, but many of you 33:50.990 --> 33:52.290 probably don't write compilers. 33:52.290 --> 33:53.610 So the first place you might want 33:53.610 --> 33:55.193 to start if you needed to compile even 33:55.193 --> 33:57.440 standardized JavaScript is you need a parser 33:57.440 --> 34:00.620 and Esprima and Acorn are two good examples of that. 34:00.620 --> 34:03.200 Escodegen. It goes the other direction. 34:03.200 --> 34:04.990 It takes something that's been parsed 34:04.990 --> 34:08.870 and it reconstitutes it as code that can run in the browser. 34:08.870 --> 34:11.290 So you parse code into what's called an AST, 34:11.290 --> 34:14.178 it's a fancy tree, you make changes to the tree, 34:14.178 --> 34:16.219 and then you run it back through a code generator 34:16.219 --> 34:17.480 and you get code back. 34:17.480 --> 34:20.300 And that's the basic cycle that it takes 34:20.300 --> 34:22.570 to do coding tools like this. 34:22.570 --> 34:24.070 That's exactly what all your editors 34:24.070 --> 34:25.779 do when they're parsing through your code 34:25.779 --> 34:27.570 and making type hints and things like that. 34:27.570 --> 34:28.650 They're doing that cycle. 34:28.650 --> 34:29.690 You can do that yourself. 34:29.690 --> 34:32.100 You can build your own tool sets that way. 34:32.100 --> 34:34.500 Escope and eslevels, they analyze 34:34.500 --> 34:36.320 the scopes in your code. 34:36.320 --> 34:38.020 And many of you probably don't actually 34:38.020 --> 34:40.909 understand how quite nested and how quite complex 34:40.909 --> 34:43.098 your scopes are and where all of your closures are. 34:43.098 --> 34:45.139 It would be nice if we could build a set of tools 34:45.139 --> 34:48.770 to analyze those things and even solve some of them. 34:48.770 --> 34:50.570 What if the tool could realize that you've 34:50.570 --> 34:53.100 got a bunch of nested functions that doesn't actually 34:53.100 --> 34:55.409 need to be there, so it could un-nest some 34:55.409 --> 34:57.510 of those things which would increase performance 34:57.510 --> 34:59.460 and sanity of your code. 34:59.460 --> 35:01.350 We can build tools to do that. 35:01.350 --> 35:02.916 Istanbul is for code coverage. 35:02.916 --> 35:04.790 This is another thing from the testing world, 35:04.790 --> 35:06.594 but instanbul will go and tell you, 35:06.594 --> 35:08.760 do you have places in your code that you're not even 35:08.760 --> 35:09.380 testing yet. 35:09.380 --> 35:11.030 Well, that's a good thing that you need to know 35:11.030 --> 35:12.571 and we might even be able to fix that 35:12.571 --> 35:16.250 by dropping code that doesn't exist, that isn't being used. 35:16.250 --> 35:17.405 Estraverse. 35:17.405 --> 35:19.530 That's a tool that allows you to analyze that tree. 35:19.530 --> 35:21.600 The AST is that tree I'm talking about. 35:21.600 --> 35:25.490 So you can use estraverse along with esprima and escodegen 35:25.490 --> 35:28.230 and you can use those tools to understand the code better. 35:28.230 --> 35:29.400 Eslint. 35:29.400 --> 35:32.600 Fantastic there's js.lint and js.intel out there as well, 35:32.600 --> 35:35.240 but eslint is the most configurable linter 35:35.240 --> 35:36.262 that I've seen. 35:36.262 --> 35:38.220 And by the way, just as a side note on linters. 35:38.220 --> 35:41.010 Linters are about style opinion. 35:41.010 --> 35:43.150 They're not about program correctness or validity 35:43.150 --> 35:44.066 or anything like that. 35:44.066 --> 35:45.610 They're a set of opinions and this 35:45.610 --> 35:49.380 is perfectly configurable to your own set of opinions. 35:49.380 --> 35:51.660 So it shouldn't hurt your own feelings. 35:51.660 --> 35:53.580 And plato.org and jscomplexity.org 35:53.580 --> 35:55.880 provide tools that actually analyze 35:55.880 --> 35:57.372 the cyclomatic complexity. 35:57.372 --> 35:59.330 That's a fancy way of saying how many functions 35:59.330 --> 36:01.270 are calling other functions. 36:01.270 --> 36:03.021 Analyze that and perhaps even fix it. 36:03.021 --> 36:05.270 These tools just analyze it, but you could build tools 36:05.270 --> 36:09.024 on top of that allowed you to simplify your code without you 36:09.024 --> 36:10.065 having to worry about it. 36:10.065 --> 36:11.600 You write some complex code and instead 36:11.600 --> 36:13.099 of you having to think about it, you 36:13.099 --> 36:15.320 could go through and programmatically figure out 36:15.320 --> 36:18.130 how to simplify the code. 36:18.130 --> 36:19.120 So some use cases. 36:19.120 --> 36:21.599 You can auto correct misspellings. 36:21.599 --> 36:23.390 And that would go for any of our languages, 36:23.390 --> 36:25.180 but I'm specifically talking about JavaScript here. 36:25.180 --> 36:26.638 You could auto correct misspellings 36:26.638 --> 36:30.050 of variables or auto correct misspellings of keywords 36:30.050 --> 36:31.000 or things like that. 36:31.000 --> 36:33.380 You can safely rearrange the scope like I talked about. 36:33.380 --> 36:35.510 You could consolidate your variable declarations 36:35.510 --> 36:36.390 automatically. 36:36.390 --> 36:38.370 You could automatically reduce complexity. 36:38.370 --> 36:41.460 You could refactor those terrible, awful Boolean traps 36:41.460 --> 36:43.440 that we design into our function calls. 36:43.440 --> 36:45.650 You could optimize the performance of your code 36:45.650 --> 36:47.740 and the list goes on and on and on. 36:47.740 --> 36:50.210 We haven't even begun to scratch the surface of JavaScript 36:50.210 --> 36:50.710 tooling. 36:50.710 --> 36:54.320 And I tried to give you just this quick, little glimpse 36:54.320 --> 36:57.440 into some of the things that we might be able to do. 36:57.440 --> 37:00.520 And by the way, there's a couple of really fantastic talks 37:00.520 --> 37:02.730 that I think you should definitely pay attention to 37:02.730 --> 37:03.696 out there. 37:03.696 --> 37:05.070 So the first one you'll just have 37:05.070 --> 37:06.611 to get the slides to get these links, 37:06.611 --> 37:10.585 but the first one by Greg here it's a fantastic talk 37:10.585 --> 37:12.200 and then there's another one-- I'm 37:12.200 --> 37:15.190 sorry the one is by Greg and the other one is by Aria. 37:15.190 --> 37:18.535 So these are fantastic talks about tooling in JavaScript 37:18.535 --> 37:19.910 and they go into even more detail 37:19.910 --> 37:21.260 about some of these tools. 37:21.260 --> 37:24.026 So I highly recommend that you check those out. 37:24.026 --> 37:26.516 In the style of Steve Jobs, I have one more thing, 37:26.516 --> 37:28.640 one more thing that we haven't really addressed yet 37:28.640 --> 37:31.072 that might be the big elephant in the room 37:31.072 --> 37:32.780 and it's that whole idea about JavaScript 37:32.780 --> 37:36.840 and its typing system and its coercion system. 37:36.840 --> 37:37.882 This is just one example. 37:37.882 --> 37:39.965 There are literally hundreds that we could come up 37:39.965 --> 37:41.640 with out there, but this is one example 37:41.640 --> 37:43.150 that I saw someone tweet at me the other day 37:43.150 --> 37:45.730 and they were saying, this is something that frustrates me 37:45.730 --> 37:47.620 about JavaScript, the fact that if I 37:47.620 --> 37:50.140 happen to forget the parentheses, like line 5 37:50.140 --> 37:51.160 is the intended code. 37:51.160 --> 37:55.240 But if I do line 6, I get this false false error 37:55.240 --> 37:58.010 or a false false value out of it when I just 37:58.010 --> 38:00.560 forgot to put the parentheses or if I accidentally put 38:00.560 --> 38:02.430 parentheses that I didn't intend. 38:02.430 --> 38:04.410 So does this sort of thing bother you? 38:04.410 --> 38:07.169 Do have problems with JavaScript types? 38:07.169 --> 38:08.960 And many of you, I believe, would say, yes. 38:08.960 --> 38:11.400 It's a difficult problem. 38:11.400 --> 38:14.562 It's something that it's difficult to fully get 38:14.562 --> 38:16.020 your head around, but I don't think 38:16.020 --> 38:18.670 it's that difficult to get a very good working knowledge of. 38:18.670 --> 38:21.150 So I would push back against people that say completely 38:21.150 --> 38:23.660 avoid coercion, but this is one of those traps 38:23.660 --> 38:25.450 in those problems. 38:25.450 --> 38:27.850 So guess what, tools can fix this too. 38:27.850 --> 38:29.100 Here's just one example. 38:29.100 --> 38:29.860 I love this site. 38:29.860 --> 38:32.970 It's called restrictmode.org, kind of like strict mode, 38:32.970 --> 38:34.130 but restrict mode. 38:34.130 --> 38:37.830 It's a build-time tool that goes through and rewrites your code 38:37.830 --> 38:39.530 only for development time checking, 38:39.530 --> 38:42.470 but it's a build tool that will rewrite your code with type 38:42.470 --> 38:46.300 safety checks around all of the unsafe places in your code. 38:46.300 --> 38:48.320 And then it runs real values through them 38:48.320 --> 38:51.610 and it reports back warnings if you're doing things unsafe. 38:51.610 --> 38:54.090 And here is a list of the rules of the tool applies, 38:54.090 --> 38:57.080 so the less than operator can only do strings and numbers 38:57.080 --> 39:00.394 and if you do anything else than that, it gives you a warning. 39:00.394 --> 39:02.810 So if you're struggling with that in your JavaScript code, 39:02.810 --> 39:04.935 instead of going to an entirely different language, 39:04.935 --> 39:06.475 maybe you just need a smarter tool. 39:09.229 --> 39:09.770 So that's it. 39:09.770 --> 39:13.390 I hope that inspires you to think more about tools. 39:13.390 --> 39:15.700 And if you're not the one who feels confident enough 39:15.700 --> 39:18.150 about JavaScript to actually build the tools, 39:18.150 --> 39:20.340 in your learning process, you can 39:20.340 --> 39:22.674 experiment with things that would make the language make 39:22.674 --> 39:24.881 more sense to you as you learn and you can still have 39:24.881 --> 39:26.090 valuable input and feedback. 39:26.090 --> 39:28.298 And if you are somebody who likes to tinker and hack, 39:28.298 --> 39:31.077 please help build some better tools for the rest of us. 39:31.077 --> 39:31.910 Thank you very much. 39:38.730 --> 39:41.950 I can't believe you sat in the sacred question chair. 39:41.950 --> 39:43.450 I sat in the sacred question chair. 39:43.450 --> 39:44.750 I'm sorry. 39:44.750 --> 39:47.190 is this real water or is it like stage water? 39:47.190 --> 39:48.645 I fucked up. 39:48.645 --> 39:50.270 I don't even know if I could trust it. 39:50.270 --> 39:51.460 Oh, I get my shoes back. 39:51.460 --> 39:52.200 This is awesome. 39:52.200 --> 39:52.740 You ordered a coffee, right? 39:52.740 --> 39:53.440 I did order. 39:53.440 --> 39:53.720 Yeah. 39:53.720 --> 39:54.220 Absolutely. 39:54.220 --> 39:56.630 Thank you so much. 39:56.630 --> 39:57.560 Marten, everyone. 39:57.560 --> 39:58.393 Thank you very much. 40:03.080 --> 40:07.820 So you were saying we need less standards, better tools, 40:07.820 --> 40:10.770 but surely we need better standards as well, right? 40:10.770 --> 40:14.830 Like we had promises as a tool for years and years and years, 40:14.830 --> 40:17.060 but getting them as a standard, that's 40:17.060 --> 40:18.840 what's been massively important though. 40:18.840 --> 40:20.870 So I think it's important-- I'm glad you asked that question. 40:20.870 --> 40:21.953 It's important to clarify. 40:21.953 --> 40:24.250 I don't mean that standards need to go away. 40:24.250 --> 40:26.370 I mean that we can stop obsessing about, 40:26.370 --> 40:29.159 well, they didn't put it in the standard, so I can't do it. 40:29.159 --> 40:29.950 That's what I mean. 40:29.950 --> 40:32.194 I mean, that these can develop independently 40:32.194 --> 40:34.610 and I mean that what we can do with the tooling can inform 40:34.610 --> 40:36.960 what happens with the standards as we've already proven, 40:36.960 --> 40:38.740 we just need more of that. 40:38.740 --> 40:41.070 With some of these changes, what 40:41.070 --> 40:42.280 was the end game with them? 40:42.280 --> 40:44.238 Is to get them in standards or is like the idea 40:44.238 --> 40:47.304 is to test the water to see how popular they could be? 40:47.304 --> 40:48.720 I absolutely would hope that they 40:48.720 --> 40:51.530 would be willing to see if millions of people 40:51.530 --> 40:53.360 started using a particular tool and fixing 40:53.360 --> 40:54.830 of particular set of problems. 40:54.830 --> 40:56.450 That should be important input and I 40:56.450 --> 40:58.199 have every belief that they would probably 40:58.199 --> 40:59.410 take that into account. 40:59.410 --> 41:01.880 With particular respect to some of the things I've shown, 41:01.880 --> 41:03.290 these are things that I've asked about 41:03.290 --> 41:04.900 and have been frustrated about before 41:04.900 --> 41:07.550 and been told for whatever reason we're not going to fix. 41:07.550 --> 41:09.300 So rather than taking that as a brick wall 41:09.300 --> 41:11.290 that I just have to keep running against, 41:11.290 --> 41:12.950 tools can fix that problem. 41:12.950 --> 41:14.570 Are they based on things that you've 41:14.570 --> 41:17.530 gone to like the ES list with. 41:17.530 --> 41:18.030 Absolutely. 41:18.030 --> 41:18.590 That's what I'm saying. 41:18.590 --> 41:21.050 I've been to the list with some of these ideas in the past 41:21.050 --> 41:23.360 and back then I didn't understand 41:23.360 --> 41:25.910 any of the spec language, so I got slot down very quickly 41:25.910 --> 41:28.170 for not knowing what I was talking about. 41:28.170 --> 41:29.711 Well, that kind of goes back to what 41:29.711 --> 41:31.880 we were talking about yesterday and so again, 41:31.880 --> 41:34.040 getting involved in specs without having to know 41:34.040 --> 41:35.430 how specs work, I suppose. 41:35.430 --> 41:38.080 So that's a similar thing there. 41:38.080 --> 41:41.000 You can do modifications like this 41:41.000 --> 41:43.049 without knowing the whole JavaScript standard 41:43.049 --> 41:44.840 or you could kind of prove out that there's 41:44.840 --> 41:46.370 a hunger for particular changes. 41:46.370 --> 41:47.020 I hope so. 41:47.020 --> 41:48.830 That's that it's really the spirit of what 41:48.830 --> 41:51.590 I'm hoping is that this could lower the barrier of entry 41:51.590 --> 41:54.430 to some folks who can express in code the sorts of things 41:54.430 --> 41:57.250 that they do and would like to do better and use that 41:57.250 --> 41:59.764 as an expression for an informal proposal. 41:59.764 --> 42:02.430 Instead of being able to come in and understand all the language 42:02.430 --> 42:04.450 around write associativity any and all 42:04.450 --> 42:06.270 those other weird things about operators, 42:06.270 --> 42:08.210 just express the things that you want to use 42:08.210 --> 42:09.239 and the way that works. 42:09.239 --> 42:11.780 And if you have a working tool the proves that it can happen, 42:11.780 --> 42:13.120 that's even better. 42:13.120 --> 42:15.010 So with the changes that you had, 42:15.010 --> 42:17.830 what happens when it goes wrong, not in the transpiling, 42:17.830 --> 42:20.050 but in the usage? 42:20.050 --> 42:22.400 How debuggable is it? 42:22.400 --> 42:24.787 So that's really all a question about how good 42:24.787 --> 42:25.620 the tool is written. 42:25.620 --> 42:29.687 So the best answer that we have right now is source maps. 42:29.687 --> 42:31.770 Source maps are a way to take your original source 42:31.770 --> 42:34.440 code and whatever the code that's running in the browser 42:34.440 --> 42:37.560 is and map the line numbers and column numbers across all 42:37.560 --> 42:38.860 these transformations. 42:38.860 --> 42:41.479 So good tools should be at least either 42:41.479 --> 42:43.020 already doing that are on the roadmap 42:43.020 --> 42:45.290 to put in source map support and many of them 42:45.290 --> 42:46.440 are already doing that. 42:46.440 --> 42:48.610 But source maps are the way that the developer 42:48.610 --> 42:51.390 tools and the browser can put you back at the original code 42:51.390 --> 42:52.370 that you authored. 42:52.370 --> 42:54.890 So if the tool does that well, then it 42:54.890 --> 42:57.980 should be sort of opaque to you that these transformations 42:57.980 --> 42:59.140 happen in the background. 42:59.140 --> 43:01.900 And was the tool doing that or that on the roadmap? 43:01.900 --> 43:04.230 So for let-er, in particular, there's an open issue 43:04.230 --> 43:06.605 and I'm hoping somebody will help me write the source map 43:06.605 --> 43:07.350 support for that. 43:07.350 --> 43:09.240 But yeah, I mean, I believe wholeheartedly 43:09.240 --> 43:12.460 that that's the story for debugging this code. 43:12.460 --> 43:15.830 So a similar issue to that, it didn't 43:15.830 --> 43:18.520 look too bad in most of the examples that you showed, 43:18.520 --> 43:22.661 but how much are you going to modify the language until you 43:22.661 --> 43:24.035 start losing syntax highlighting? 43:26.600 --> 43:28.330 Well, first of all, syntax highlighting 43:28.330 --> 43:29.620 is just another tool. 43:29.620 --> 43:32.460 So if you wanted to extend the syntax, 43:32.460 --> 43:34.790 you could then extend the syntax highlighting tools. 43:34.790 --> 43:38.165 I wrote a syntax highlighter based on this literalizer code 43:38.165 --> 43:39.540 that I was talking about to prove 43:39.540 --> 43:42.140 that that's possible to do and if you wanted to 43:42.140 --> 43:47.090 and you'd gone significantly off field in terms of your syntax, 43:47.090 --> 43:49.790 you simply customize the syntax highlighter to affect the code 43:49.790 --> 43:51.290 that you've written. 43:51.290 --> 43:54.540 Would it be possible using the tool that's 43:54.540 --> 43:56.690 doing the transpiling to also generate 43:56.690 --> 43:59.480 from that the syntax highlighting instructions 43:59.480 --> 44:00.800 for popular editors? 44:00.800 --> 44:02.041 Absolutely. 44:02.041 --> 44:04.540 I'm not doing that yet, but I think that's a fantastic idea. 44:04.540 --> 44:06.506 Will you put a pull request on that? 44:06.506 --> 44:08.100 I'll just code it now, actually. 44:08.100 --> 44:09.530 Keep talking. 44:09.530 --> 44:11.310 So what made you write your own parser 44:11.310 --> 44:14.460 versus things like esprima and similar things? 44:14.460 --> 44:16.600 So in particular, the reason I wrote 44:16.600 --> 44:19.970 Literalizer is because let-er needed to parse 44:19.970 --> 44:21.760 through non-standard code. 44:21.760 --> 44:24.270 And if you put non-standard code into many of those code 44:24.270 --> 44:26.240 parsing tools, it will just choke and say, 44:26.240 --> 44:28.034 this is invalid syntax. 44:28.034 --> 44:29.450 And some of them have a loose mode 44:29.450 --> 44:30.950 where they just kind of leave it in, 44:30.950 --> 44:32.960 but it's kind of dodgy as to how much you 44:32.960 --> 44:34.600 can do before it chokes. 44:34.600 --> 44:37.880 So Literalizer sort of is my end around to that 44:37.880 --> 44:40.070 for significant syntax changes. 44:40.070 --> 44:42.290 I would try first the loose mode for a change 44:42.290 --> 44:44.790 and if that was good enough, I'd use that. 44:44.790 --> 44:46.375 But I wrote my own simple parser. 44:46.375 --> 44:47.625 It's not even really a parser. 44:47.625 --> 44:50.020 It's just regular expression pattern matching 44:50.020 --> 44:53.660 and that only works because the complex literals are already 44:53.660 --> 44:55.370 taken out of the picture. 44:55.370 --> 44:57.370 But I wouldn't advocate that everybody just 44:57.370 --> 44:59.720 go out write their own parser from day one, 44:59.720 --> 45:01.720 it's just the step that I had to take to do 45:01.720 --> 45:03.460 what I was doing was let-er. 45:03.460 --> 45:10.600 So if this is a parser built to understand new things, 45:10.600 --> 45:12.500 are you editing that parser just say 45:12.500 --> 45:16.050 for each change you make or is it-- what does it recognize? 45:16.050 --> 45:18.124 How does it recognize separate things? 45:18.124 --> 45:19.290 So that's a great question. 45:19.290 --> 45:21.440 That's the ongoing area of research that I have, 45:21.440 --> 45:24.400 which is right now these are individual, discrete tools that 45:24.400 --> 45:25.920 do just one task. 45:25.920 --> 45:28.080 So let-er just does the block scoping 45:28.080 --> 45:29.720 and this tool just does that. 45:29.720 --> 45:31.600 And right now that's complex because then you 45:31.600 --> 45:33.620 have to have several tools in a tool chain. 45:33.620 --> 45:36.649 This whole FoilScript idea is that eventually one tool 45:36.649 --> 45:38.190 could understand all the rules and do 45:38.190 --> 45:39.829 all the transformations in one. 45:39.829 --> 45:41.620 That's still just an area of open research. 45:41.620 --> 45:43.280 But sort of proof of concept, I've 45:43.280 --> 45:45.850 already proved that individual changes can already happen. 45:45.850 --> 45:50.180 So when you're transpiling from your own thing into ES6 45:50.180 --> 45:53.260 and then down to ES3, can we coin 45:53.260 --> 45:55.090 that as the human centipede approach? 45:55.090 --> 45:55.590 Absolutely. 45:55.590 --> 45:57.030 I love that. 45:57.030 --> 45:59.350 That's a fantastic way of describing it. 45:59.350 --> 46:03.380 So if I'm using a tool for npm or whatever 46:03.380 --> 46:05.170 and I find a bug in it and I think, 46:05.170 --> 46:08.315 yeah I've got a little best bet I'm going to try and fix 46:08.315 --> 46:10.230 this and help the community. 46:10.230 --> 46:13.870 I go to GitHub and it's written in CoffeeScript. 46:13.870 --> 46:14.780 Fuck that. 46:14.780 --> 46:16.544 Not because I dislike CoffeeScript, 46:16.544 --> 46:17.960 but I'm going to have to learn it. 46:17.960 --> 46:19.710 Right. 46:19.710 --> 46:22.520 Are you talking about massively multiplying this problem? 46:22.520 --> 46:25.410 So it's important to understand that I'm not necessarily 46:25.410 --> 46:28.740 suggesting that every code repo out there on the planet 46:28.740 --> 46:31.217 would have their own willy-nilly versions of code. 46:31.217 --> 46:33.050 I'm more suggesting this is the sort of code 46:33.050 --> 46:34.880 that I want to author and then there 46:34.880 --> 46:37.360 would be an agreed-upon standard which might be ES6 46:37.360 --> 46:39.846 or it might be your own team version of that standard, 46:39.846 --> 46:41.470 but it would be an agreed-upon standard 46:41.470 --> 46:45.680 and the tool could go two way between those two standards. 46:45.680 --> 46:47.674 It's possible that you would have two commits. 46:47.674 --> 46:49.840 You would have your own version of a JavaScript file 46:49.840 --> 46:52.180 just like people have source CoffeeScript and then 46:52.180 --> 46:54.980 the compile JavaScript and you could do that in your git-repo 46:54.980 --> 46:56.370 if that made sense as well. 46:56.370 --> 46:58.760 But you would presumably be accepting full requests 46:58.760 --> 47:02.210 into the source file which is the one written 47:02.210 --> 47:03.397 in the new style, right? 47:03.397 --> 47:05.480 Like that's how CoffeeScript's repo used to do it. 47:05.480 --> 47:07.440 I think that's the most likely scenario, 47:07.440 --> 47:08.898 but it doesn't have to be that way. 47:08.898 --> 47:10.524 The only thing after except really 47:10.524 --> 47:11.940 is that if you go down this route, 47:11.940 --> 47:13.944 it requires the tools because it's not something 47:13.944 --> 47:15.860 that you're going to automatically do the hand 47:15.860 --> 47:16.526 offering around. 47:16.526 --> 47:18.390 But if you already have a build process 47:18.390 --> 47:20.431 and you already have concatenation you're already 47:20.431 --> 47:23.600 transpiling, this is just one more step in an already 47:23.600 --> 47:25.200 pretty-well defined process. 47:25.200 --> 47:27.680 So earlier Nicholas was talking about the benefits 47:27.680 --> 47:31.080 of standardizing on one approach with a team. 47:31.080 --> 47:33.100 Why do you hate him so much? 47:33.100 --> 47:34.100 Why do I hate him? 47:34.100 --> 47:35.580 I don't hate him at all. 47:35.580 --> 47:38.460 But I do actually find it interesting 47:38.460 --> 47:41.620 that there is a constant struggle between this very sort 47:41.620 --> 47:44.250 of we got to standardize and make everything opaque, 47:44.250 --> 47:47.260 just totally abstracted away versus the other extreme, 47:47.260 --> 47:49.197 which is, I want bare bones knuckle. 47:49.197 --> 47:51.530 And a lot of people might look at what I'm talking about 47:51.530 --> 47:53.050 as that far extreme. 47:53.050 --> 47:54.920 I still see mind self sort of in the middle 47:54.920 --> 47:57.080 because there are definitely abstractions. 47:57.080 --> 47:58.260 You brought up promises. 47:58.260 --> 48:01.670 Promises are an abstraction, but they're a fantastic abstraction 48:01.670 --> 48:04.350 and we should build off of them, but not all abstractions 48:04.350 --> 48:05.430 are good. 48:05.430 --> 48:08.220 I don't necessarily think that that's an open-ended statement 48:08.220 --> 48:10.390 that we should just abstract everything. 48:10.390 --> 48:13.594 But as you say, not just promises, but also 48:13.594 --> 48:14.510 what we saw with SaaS. 48:14.510 --> 48:18.390 This is proving that these transpilers are approving out 48:18.390 --> 48:20.550 features that actually end up in the main language. 48:20.550 --> 48:23.290 And I think that's a very important thing in the CSS 48:23.290 --> 48:25.950 ecosystem and I'd like to see more people trying to do that 48:25.950 --> 48:27.650 in our JavaScript ecosystem. 48:27.650 --> 48:31.240 So I noticed that you didn't show any code that 48:31.240 --> 48:33.670 made these transformations on how you define 48:33.670 --> 48:36.030 them or I didn't spot it. 48:36.030 --> 48:36.530 Why? 48:36.530 --> 48:39.450 Is that bad? 48:39.450 --> 48:41.515 I didn't show the source code of let-er 48:41.515 --> 48:42.630 is what you're saying? 48:42.630 --> 48:45.205 Well, not just let-er. 48:45.205 --> 48:47.580 Is let-er the thing that is doing all the transformations 48:47.580 --> 48:50.160 you spoke about or is it a tool that you can use 48:50.160 --> 48:51.480 to write transformations in. 48:51.480 --> 48:51.980 Yeah. 48:51.980 --> 48:56.070 So FoilScript is this describe your rule sets 48:56.070 --> 48:59.287 and that would be in JSON, but it's not finished yet. 48:59.287 --> 49:01.870 And what I'm doing right now is building the actual tools that 49:01.870 --> 49:03.480 will do the transformation and then 49:03.480 --> 49:05.271 eventually you'll have something that wraps 49:05.271 --> 49:06.570 around that with the rule sets. 49:06.570 --> 49:08.620 So I didn't show the rule sets because they don't exist yet, 49:08.620 --> 49:09.480 but they will. 49:09.480 --> 49:13.330 So where do you think-- this is kind of more a general ES6 49:13.330 --> 49:13.960 question. 49:13.960 --> 49:15.418 Is there a particular area that you 49:15.418 --> 49:19.490 think that they're going in the wrong direction or things 49:19.490 --> 49:21.210 that they could change? 49:21.210 --> 49:22.790 Yeah. 49:22.790 --> 49:26.940 So first off, again, mad props to the TC39 Committee. 49:26.940 --> 49:30.410 They've done a fantastic job with the vast majority of ES6. 49:30.410 --> 49:33.140 They are completely wrong on the topic of class. 49:33.140 --> 49:35.670 The class keyword does not belong in JavaScript. 49:35.670 --> 49:36.750 It's a terrible idea. 49:36.750 --> 49:39.310 It's going to make everybody's understanding of the language 49:39.310 --> 49:40.810 worse rather than better. 49:40.810 --> 49:43.604 So boneheaded mistake there. 49:43.604 --> 49:46.270 That's one of the rare few areas that I agree with Doug Crawford 49:46.270 --> 49:48.660 because he also doesn't like class. 49:48.660 --> 49:52.710 But in other places, there's a lot of great stuff. 49:52.710 --> 49:55.334 --with something like class because I think we do need 49:55.334 --> 49:57.750 something to make that prototype of Harrison's a bit 49:57.750 --> 49:58.150 easier. 49:58.150 --> 49:59.858 Do you think that's the domain of macros? 49:59.858 --> 50:01.710 Is that way you could do that sort of stuff? 50:01.710 --> 50:02.876 Actually, I don't think so. 50:02.876 --> 50:04.430 I think object.create is all we need 50:04.430 --> 50:06.400 and that's been built since ES5. 50:06.400 --> 50:09.090 It's the utility that creates an object 50:09.090 --> 50:10.920 and links it to another object. 50:10.920 --> 50:13.470 So rather than thinking about designing our code 50:13.470 --> 50:16.480 in class abstraction, we use delegation 50:16.480 --> 50:17.439 as our design patterns. 50:17.439 --> 50:18.980 It's a very different design pattern. 50:18.980 --> 50:20.560 We use delegation as a design pattern 50:20.560 --> 50:23.060 and you just build objects that are linked to other objects. 50:23.060 --> 50:25.100 I call that OLOO, by the way, objects 50:25.100 --> 50:26.100 linked to other objects. 50:26.100 --> 50:27.808 And it's a very simple way of doing that, 50:27.808 --> 50:30.195 and again, I've written a bunch about that online. 50:30.195 --> 50:30.695 Cool. 50:30.695 --> 50:31.710 I'll check that stuff out. 50:31.710 --> 50:32.918 --if people are interested. 50:32.918 --> 50:34.240 Kyle Simpson, everyone.