 Jeremy Ashkenass is the creator of Backbone, the creator of UnderSchool, and the creator of CoffeeScript. I don't think I need to say any more than that. Give him a big round of applause. Jeremy Ashkenass. Thanks. Good morning, everybody. I hope you're all are feeling well and rested after a successful last night. And I'm glad to be here. It's good to be in Barcelona. I had a chance to come visit about a year ago. And I liked it so much when when Jose asked me to come talk at this conference, I figured I'd jump at the opportunity. So today we're going to talk a little bit about keeping in theme with the conference with the coolest intro music and smoke machine. We'll talk a little bit about the future of JavaScript or at least some possible potential futures of JavaScript. And so I work at the New York Times. I've been physically there working for about five years now with a one year off good behavior. And I usually work in the newsroom on the graphics team these days. So working on sort of fun fiddly interactive graphics and visualizations and working with databases to, you know, do some reporting and figure out what the interesting parts of the dataset are, how best to convey them to the readers and then how best to display and represent them. And it's a fun job, but it's not very traditional JavaScript programming. So JavaScript isn't the whole, you know, nine yards of what you're working on. You're also working on the story a little bit. You're working on database queries. You're working on SQL. You're working on backend stuff and you're working on front end stuff. But the main difference between, you know, your normal startup style JavaScript programming and working in a newsroom is sort of the pace of the project, right? If you're on a big startup project, your code needs to be really good and it needs to, you know, be well-factored and it needs to play nicely with other people's code. It has to be maintained for a long period of time and it sort of needs to stay in the test of time because it is the project that you're building that you want to keep using and reuse that code for a good, hopefully at least a couple years, whereas with a graphic, often the code needs to work for about one day and after that 24 hours, you're never going to touch it again and you don't have to worry about it. If it's a big mess, if it's a big hairball, that's okay. So the rules are a little bit different, but I think it's fun to have sort of both influences when you work on things. Keeping in mind, you know, the longer term aspects but also just blank slate, you know, you have 24 hours before the deadline hits. What can you do with this dataset and 24 hours go? And if you don't finish, then it doesn't matter because the story is gone and it's too late past that point. So when you're talking about, you know, the future of JavaScript and where it might go, sort of the productive place to start is with thought experiments, you know. If you could imagine ways that you would change the language or possible alternative ways of getting the job you want to get done accomplished, what are some of the designs you might, what are some of the changes you might make to the language, some of the things you might take into account? And one of the first big things that limits you a little bit is at least in terms of what can actually be done for JavaScript itself is sort of the curse of JavaScript, which is backwards compatibility in a big way. So if we're talking about JavaScript changing or the possibility of JavaScript changing, the biggest problem with that notion is that, you know, far larger than JavaScript, the language itself and the difficulty of making changes to it in terms of technical implementation is that you have the entire web already out there and the entire body of code that already exists and is programmed for the web and all of the weird corner cases that it uses or some sites use and take advantage of and all of the bad practices or anti-patterns that exist in running JavaScript on the internet today, you have to keep supporting all that stuff, right? You can't break any of it. And it's often, if you read through some of the TC39, the committee that works on the JavaScript spec, if you read through some of the minutes where they're discussing features, frequently don't break the web, you know, oh, we'd love to do that, but we can't break the web is a big concern. So if we're talking about the existing language and making changes, this is a huge limiting factor in what can and cannot be done. So let's not necessarily worry about that too much, but sort of keep it in mind in terms of real possibilities. But a good place to start is with lessons that you've learned from the trenches. So in your day-to-day work, you know, what are the things that have caused you grief when they didn't need to? What are the things that you've learned how to do because they've proven useful time and time again as opposed to maybe doing it the naive way and sort of start with things that you know you have trouble with today? Because sort of under the hood, you know, JavaScript is really fundamentally quite a beautiful language and it gets a lot of things right. And there's no need to go and muck about with things that are already working well when we know we have things that trip us up and we have trouble with. And so there's also another really interesting characteristic of JavaScript as a programming language that's very different than almost any other programming language. And that is that you can't just throw more code at the problem. So usually if you're talking about a server-side language, there's no real penalty to building up larger and larger abstractions and more and more complex and involved ways of getting your problem done because it's just code and you can run it and as long as it works, that's fine. But in JavaScript land and historically this has been true because you have, you know, slower internet in the past and you have browsers like IE6 and IE7 in the past that choke, you know, literally choke if you try to feed it too much JavaScript too quickly. And this is actually still a concern today because of mobile browsers and caching limitations in mobile browsers and bandwidth limitations if you're trying to use the net over an older network infrastructure. And so you can't really get away with just throwing code at the problem. You have to sort of be a little bit smarter than that. So if you're going to make a change or you're going to introduce an abstraction or you're going to design a library, it behooves you and it pays off to think about ways you can get your goal accomplished without introducing a large level of supporting code that needs to be running in the background. So if you have the same feature and you can design it two ways and one way needs, you know, a 25K runtime to support the feature and the other one sort of inlines the feature only when you use it, only in the places that you use it, so you're only paying for the small pieces of the library that you use, then that sort of design is going to flow a lot better with the limitations of the web today. Some other lessons learned from the trenches. This one might be a little bit controversial, but I think we've learned this lesson well in the past that quote-unquote polyfills can really get you into trouble if you're not extremely, extremely careful with what you're doing. So here I'm saying polyfills, but we could say monkey patching or extending native objects or filling in bits on the native level that are exposed globally. So one of the famous examples of this becoming a problem is Prototype.js, and having a version, not even, it's a different function, it's not even a version of array.prototype.reduce by default being extended at one point on to every array, and it did something different, right? So this version of reduce is a function that gives you back if the array has more than one element, then it gives you back the full array, otherwise it's just the head, it's just the first thing in the array, so it sort of unwraps it if it's a single element array. And this, you can see what might happen here if you are working with a library, and at the library says, if array.reduce is defined in the normal way, I'm going to try to use it. And then someone else includes prototype on the page, and all of a sudden all of these other unrelated pieces of code break. And this one, you might say, oh, you know, this is obviously not a real polyfill because it's not doing the right thing, it's an unrelated function, if they had implemented reduce correctly it would be okay. And that's sometimes true, but it's not necessarily true. So here's a much more popular one. This is Crocford suggestion for, or at least in 2008 this was suggestion for what you should do with object.create. So if object.create doesn't exist as a function, let's define it. So object.create is going to be a function. We're going to make a new little inner function as our class there. We're going to set its prototype to the object you pass in, and then we're going to return a new instance of it. And so that's a really useful little function to have. The problem is that if you call it object.create, you've now just claimed sort of responsibility for both what the spec says object.create does right now, and also what the spec might say it will do in the future if they extend it and add new features to it. And so if you load this version of this polyfill onto the page and code exists that expects object.create to work in the spec approved way, that code will probably break because it thinks if object.create is defined, I better be able to pass property definitions into it. And if you can't pass property definitions into this version, that expectation is going to be violated. So that's sort of one lesson from the trenches. Another one is the notion of defensive programming. So you're happy in JavaScript land, you're scripting along, you're adding some marquee tags to the page, making things blink, having your pop-up alert boxes go and everything is going just fine. But you remember getting into trouble when you're not defensive enough about what goes on with your code. When you leak global variables to other parts of the page, and this is something that maybe I'm a little bit more familiar with than your work in an average sort of controlled environment if you're working on your own application, on your own web server, in your own product because in a newspaper on an article page or on a home page, there is a whole ton of other people's JavaScript that's being run. There's all kinds of ad code and tracking code and carousel widgets, slideshow widgets, all these things being written by different teams, being written on different continents and different languages with different goals, right? The advertiser doesn't really care if they screw something up for your implementation. The guy who built the slideshow three years ago has long gone and no one knows where he is. So all of this code has to get along and all of it has to coexist on the same page without stepping on each other's toes. And so one of the things that we've learned is that it's too easy in JavaScript to leak global variables or even variables that are namespaced down a little bit that will conflict with other parts of the code. Sometimes you see an advertising script that every single A, B, C, D, E, F, every single letter variable, because it's minified and it's removing its VAR statement also just because and also A, B, A, C, A, D, all of those variables are now defined up on the global space. And this is actually a problem for us because in document cloud, the one namespace that we use to export our public API was DC for document cloud. So when this advertising code had all of the possible combinations of two letter variables exposed as its local variables, it would clobber that namespace and get rid of it. So defensive programming is kind of important. Not relying on inadvertent global state, so not designing your script so that it assumes maybe at page load there's some property on the page, some DOM element you can measure or a JavaScript variable that you need that exists, but you shouldn't assume it's always going to be around, right? So if you need it, you should look at it when you know it's going to be there, make a copy of it or a reference to it internally, and then if later something bad happens to it, you know, you've been defensive, you've already have your local version, you're not relying on global state all across the page the entire time. And then monkey patching and or polyfilling or native extensions is the other one. So if you are going to be a good citizen, then you both have to not polyfill or monkey patch core objects for your purposes because someone else might be expecting a different polyfill or a different patch, but you also have to be defensive against someone else doing it to you. So one way to do that is to compare the version against the native version. So one example is when someone passes you a list of something and you want to call reduce on it, but you're not sure if the reduce on that is native or not, you can check because you've saved a copy of a reference to the native reduce at page load and you can just say if it is what I'm expecting it to be, then I can use it. And if it's not what I'm expecting it to be, I've checked and so I know that's not the case and I have to use my fallback at that point. Another example of sort of things we've learned from the trenches is that there is this massive amount of befuddlement and confusion around prototypes in JavaScript, right? To the extent that it's very frequent on threads talking about prototypes and how to use prototypal inheritance in JavaScript for people to say things like JavaScript isn't object-oriented, which is just bananas, right? JavaScript is a deeply object-oriented language where arguably more object-oriented than even languages like Ruby, which are themselves quite extremely object-oriented. Strings, regexes, functions, arrays, objects, basically everything in the language is an object, everything in the language can be extended at runtime and it's an extremely valuable piece of the whole JavaScript setup. So if we're imagining a future language, what's a way to reduce confusion and befuddlement around prototypes? How can we make it clear that prototypes are not easy to use but they can be easy to use and they're extremely useful when you're trying to make many instances of a single-shaped object that all are alike in some way, then prototypes are a great recipe for getting that done. So my sort of experience with this notion of trying to imagine what a different version of JavaScript could be is with CoffeeScript. So CoffeeScript is a little language that compiles down to JavaScript and it introduces a few things and it takes away a few things and it sort of focuses on these particular lessons learned and these particular patterns that if you do a lot of JavaScript, these are the things that you find yourself addressing with sort of boilerplate code over and over again and the idea with CoffeeScript is just to be a very conservative way of sort of drying up those little repeated patterns and putting them into language instead of having them something you have to remember or something you have to agree on with the rest of your team. And so classes are one of those things, right? So if you have all of the prototypal confusion basically in JavaScript, if you're working with a prototype, you're doing something like this and you have a constructor function. The constructor function has a property called prototype and when you point that to an instance of another object, then whenever you create a new entity in this case, all of its fields are going to by default have what model has. And so looking at this, this is just sort of your basic how you work with the naive prototype in JS and there's already some gotchas and some confusion. So for one thing, it's all sort of ad hoc, right? We're just doing this one step at a time. At first, we have a function. We don't even know if it's supposed to be a class or not at that point because it's just a function. And then when we assign the prototype, we start to get a picture of what it is we're trying to do here. But this is already a little bit fraught with peril because I have to create a model here, right? If the constructor of that model has side effects, if it does something, if it's going to error out, if it doesn't have the right data, then this is already a problem and I need to find some way of getting an instance of that model. Just I don't need it for anything, right? I just want to inherit from it. It doesn't have to be saved to the database. It's not going to be used for anything. It's just purely a reference for me to point this prototype to. So you have to get a hold of one of those, which can be more difficult than it first seems. And then sort of ad hoc one at a time, you're defining properties back on your class, which is debatably OK. So a safer way of doing this might be to do the whole juggling trick where instead of instantiating the model, I make a temporary constructor function that's not going to be used anywhere else. I assign the prototype of that to the prototype of model, create a new one of that, which I know doesn't have any side effects because I've just created it as an empty function, and then use that sort of proxy surrogate object as my prototype for the entity. And so it's like a six-step dance that is the safe good quote unquote way of working with prototypes, but it's just a whole bunch of boilerplate and a pattern that you have to do over and over and over again. So how can we clean that up? So in CoffeeScript, a function is just a arrow where the endpoint points to the output. So the left side of the function points to the results. And so here we have a class called entity. It extends model. It just does exactly that little surrogate prototype trick that I described. And then you have your two functions, which are defined on the prototype indented inside of the class. So that's just a little example. Another fun one is destructuring assignment, which is also in so some version of classes are on the schedule to be in the next version of JavaScript. And to sort of reiterate again with the prototype confusion, the classes are prototypes. It's the exact same thing. It's not classes or prototypes. They don't work differently. They're not two different ideas that aren't compatible. It's just that the prototype is sort of, it's an implementation concern. And you've always had classes this entire time. They're just, if you call them a constructor function, the constructor function is, it sort of literally is, the class object that you're working with. It is the abstract thing that you don't, that isn't a concrete instance that you use to refer to the parent's behavior. And so having classes in the next version of JavaScript is just a way of making that manifest and making that explicit and drying up all of the possible ways that you can make an error when you're trying to inherit from a parent prototype. Sort of get that all done for you as a language should do. So destructuring assignments, another one that is shared with ES6 and with CoffeeScript with more or less the same syntax also. And the basic idea here is kind of a nifty one. It's pretty cool. It's that you have structured data and structured objects in JavaScript. So you think JSON, right? So JSON is, you have your arrays, you have your objects, you have your nested arrays and objects, and then you have values inside of them. You have strings and you have numbers and other objects and other arrays within. And so destructuring is this cool idea of saying, all right, so what if we take this big nested object and instead of having it on the right hand side as the value, we put it on the left hand side as the variable, which at first sounds like a crazy idea. Like how can you assign this, literally this big crazy nested object to a value? And the way that you do it is you walk down into that object and you follow its structure and for every piece of the object that's defined and that's structured, you line it up with the right hand side. And for everything that's not defined, so the free variables that are in spots inside of your object, those take the values of the equivalent thing on the right hand side. So whatever is in that same place in the structure becomes the value. So in this case, we have an object with a property value. The property value is an array. We have the first, second, and third variables in the array and the first, second, and third positions in the array at indexes zero, one, and two. And then that's assigned to the same structure on the right hand side. So after that line of code runs, first is one and second is two and three is, third is three. So that's one little example of using it, but sort of contrived, right? You wouldn't normally do this. Although one interesting thing to note here is that in this, if you look at the left hand side, if you had three free variables, just var first equals one, var second equals two, var third equals three, then the two values are the same and that those values are what you get back out. So in a sense, it's sort of parallel. So when you do this active destructuring, you end up with the three variables and if you had the three variables there before, then the left hand side would have produced the right hand side. You know what I mean? It's sort of this mirror version. You get back out the variables that you would have needed to create the right hand side in the first place. So that's pretty fun. It can be used for parallel assignment. So if you wanna swap places, swap two things without creating a third temporary variable, you can use it for that. And then the really fun stuff is with big JSON objects, you have a tree you need to walk down into and extract values from. You can use this to destructure that JSON object or for things like options hashes where you have a big hash of options and you wanna pull out specific values. So this last one is actually just a coffee script thing. It's a shorthand where if you have an object and you don't have key colon value, you just have keys named, then it assumes that the value is the same name as the key. So this is the equivalent of error colon error comma success colon success as a shorthand way to extract out options.success and options.error. So that's destructuring assignment. Another good one also from the trenches, although this one is probably the single most controversial thing in all of coffee script is automatic variable declaration. So the idea here is that one of the most confusing things for beginners when you're just starting out with any programming language. So in my case it was Java back at a school lesson is like even before you're confused by recursion and even before you're confused by closures, being confused by variables is sort of step one. So this idea that up here in my program, I can say x equals five and then down here in my program, I can say x equals 10 and that that's not a problem. That's not some sort of a conflict, right? Cause just if you're first trying to learn it and you don't have this sort of mental model of how variables point to values, you think of it as sort of a math equation where if you're saying that x is five, then how can it be 10? And how does that sort of translation work? I thought that x became five, so how can I make it something else? So one of the things that CoffeeScript tries to simplify is to get rid of this notion of the difference between declaration and assignment. So the idea that declaring a variable is one thing as a name in a particular scope and actually giving it a value is a totally different thing and you can mix up both of them and have in one place in your program, you can have many different values for the same name. So x can be five and it can be 10 and it can be 15 all at the same time, but only one of those you can see and the rest of those things have been shadowed. So it tries to get rid of that whole notion because there's no reason why you ever really need to have the same name being used for five different things in the same lexical place in your function, in your program. You can always pick a different name, have a better name for each of the different uses. So in CoffeeScript, in a given lexical scope, there's only one name, x is only one thing, right? So if you say x and you can change what the value is, but you can only, within a given lexical scope, you can only ever refer to that one x. You can't have two different x's that are two different values at the same time. And that removes the need to think about sort of when you need to declare, when you don't want to declare. As long as you have an x that's visible in that lexical scope, it will be that x and not some other x that you might have created internally. So another sort of thing from the trenches is the prolifer, and this is a little bit of a, you know, of a sad thing because it's totally unnecessary, but the proliferation of different flavors of functions in JavaScript. So ideally, you'd think a function is a function, you just have one kind of function and it works the way you expect and you go from there. But of course, in JavaScript, you have function expressions where the function is a value and it's anonymous, quote-unquote, it's quote-unquote anonymous. You assign it to a variable or you have it as a callback or a property and you have function declarations where the function is not really first class. It's always, a function declaration is always against the root of your scope. It's not a value and it's named and it's not anonymous. And then you have named function expressions which is sort of a mixture of function declarations and function expressions where it is a value but it's also named and there's bugs relating to that which means that they haven't been very safe to use, at least in terms of Internet Explorer for a long time. So that's already three different kinds of functions. They all behave slightly differently. Hoisting works differently with them and the bugs between them work differently and so it's already two more things than you should really have to know to work with functions in JavaScript. And then after ES6 we're probably gonna have a couple more. So we're probably also gonna have arrow functions in addition to those three where the arrow function has the different syntax and it also has a different rule for how this is scoped, it'll be lexical instead of dynamic. And then we'll also have generators which are another new type of function that looks like a function but it actually behaves entirely differently. So it's a whole proliferation and I think if you're imagining a different sort of language you'd like to just boil that down and only have one. And so CoffeeScript actually sadly has two but it's for kind of an inherent reason. So in CoffeeScript you have the thin arrow which is your regular arrow function that is like a normal JavaScript expression. It's not a function declaration and it has dynamic this. And then you also have the fat arrow where the this is lexical. And so this of course is probably the single most difficult thing for beginners learning JavaScript because it totally takes you by surprise if you're expecting it to behave normally the first time you use JavaScript. So like most scripting languages these days JavaScript is almost entirely lexically scoped. So whenever you talk about a value the value is determined by the code that surrounds it. So if you look at the surrounding at the previous at the current block of code and all of the immediately preceding blocks of code on the page that tells you exactly what the value should be at the time you're looking at it. And this behaves completely differently. This is dynamically scoped. So the value of this has nothing to do with the value of this in the function surrounding it. It matters how you call it, right? So if you are not attached to anything and your function is being called nakedly then this will be the global object, it'll be window. If the function that you're calling happens to be attached to an object when you call it the value of this will be that object. And if the function is on a prototype it's not that the value of this will be a reference to that prototype when you call it. It's that it'll be a reference to the instance. And so this is totally wild and crazy and you'd think that it's not something that JavaScript needs but it actually it's inherent to the way that JavaScript prototypes are built. So the reason why this is dynamic and that it behaves so strangely is exactly because when we were defining those functions and attaching them to the prototype we were doing it ad hoc. So because those functions are just raw functions and JavaScript doesn't know necessarily that they're gonna be on a prototype or not be on a prototype in the end because they're just free floating this has to be dynamically scoped because there's no way for the runtime to know that it's part of a prototype otherwise and to make it and to give it the correct value of this when it's being called as an instance. So it's sort of a necessary evil that falls out of the design of prototypes that this works the way it does. And this is, it's interesting being dynamically scoped is interesting because it's so rare these days. Dynamic scoping was sort of the default scoping for everything for all variables back in the early days of LISP and the earliest implementations of LISP because in terms of actually implementing scoping in a dynamic language it's easier to do dynamic scoping than it is to lexical scoping. All you have to do is keep track of your call stack and that tells you what the values of variables are. But thankfully we've gotten past, after scheme we've gotten past that these days. So another final thing that CoffeeScript adds in terms of its experiments is everything is an expression. So part of the idea here is sort of first classness the idea that any syntactic piece of your program should be able to use in any context. So this notion that some things are statements and some things are expressions and never the twain shall meet. You can't use a statement as a value is a little bit silly because there's no reason to have statements except for things that inherently are flow control constructs like return, right? Return can't be an expression because it's telling you something about flow control. It's telling you to get out of the function. I can't say a equals return five. That just doesn't make any sense. But there's lots of other things that do make sense as expressions. So if else, right? If condition, this thing, otherwise that thing, the value of that if else, quote unquote statement should be the result of that if else, right? And so at this point you've now eliminated a distinction between an if else statement and a ternary condition, right? A ternary is simply an if else that happens to be an expression. So if your if else's are already expressions, you don't need to have this additional mental construct of also having a ternary. And so CoffeeScript does that for if else. It does that transformation for try catch, right? The value of a try catch is either the successful thing you tried to do or if there was an exception and you caught it, it's the result of that catch clause. And for switches, right? If you're gonna switch and then have a whole bunch of different things, the value of that switch is the one that succeeded. And then ultimately and a little bit more controversially for loops. So then CoffeeScript, we say that the value of a loop is the result of each iteration through that loop. So you might skip over some indexes or continue or break in your loop, but the resulting value is the array of all of the results computed by that loop. And so you get sort of array comprehensions for free because an array comprehension or an object comprehension is just simply the value of that loop. So that's probably the single most significant change that CoffeeScript does to the language. So to get back to sort of other JavaScript alternatives, CoffeeScript's particular strategy is that it's just JavaScript. So it's just this exercise of taking existing really nice JavaScript semantics, these beautiful arrays and objects and these great flexible prototypes that you can make any object into a parent of something else. And it's extremely flexible as to how you work with your functions and do first class functions and do higher order functions. And just take that and try to boil it down to its essence, right? Make functions easier to write, make classes less fragile, make it harder to create accidental global variables and be a good defensive programming citizen, make it easier to index into deeply nested JSON without getting nulls that error you out and make it easier to work with comprehensions and functional programming. But still, stay really, really tight to what JavaScript does and don't try to get too far away from it in terms of semantics. But that's only one of thousands of other possibilities. So one of the original goals of the compiler was to write it and not just have it be this opaque dense bundle of code, but to try to write it in a very open... So first of all, to implement CoffeeScript in itself so that it would be sort of a test bed that if you can't even write your compiler in the language that you're designing, then have you really sort of gotten there yet? But also to use the source code for the compiler as an explanation of things you could change. So there's places where you can say, oh, I really, you know, I think CoffeeScript's all right, but I hate that automatic variable declaration. I really like shadowing and I want to have, I want to reintroduce shadowing with a new assignment, a new assignment operator. Then having the compiler be exposed and sort of written in open way and all well documented is a way for you to hook in and to make that change and have your own version that behaves the way you want it to. And I think that's a very important thing. So this is all now three years ago, four years ago. And when I would first talk about it, it was totally hypothetical. I'm like, all right, we've put out this compiler, it's all documented and broken apart. Hopefully someone will play with it. And you don't really have expectations, anyone's gonna actually take the time to do that. But amazingly, and not all of these are CoffeeScript variants, but every line on there is from the CoffeeScript wiki of a different language that compiles to JavaScript. And one big chunk of those up towards the top is folks who've taken that compiler and forked it and done their own different versions with different features. But it's pretty incredible, the number of alternative approaches and both existing languages and experimental languages and conceptual languages that folks are building to compile the JavaScript. These days. So before we go into some other ideas about the possible future of JavaScript, I think it behooves us to take a moment to think about sort of the nature of code and where we're heading with all this. So code is this really strange artifact as an artifact of human production. It's not, it's writing, it's literally writing. It's not quite prose, but it is text. But it's a very strange text, right? It tries to convey ideas, these are mathematical ideas, design ideas, it's sort of like an engineering blueprint, but it's not visual, it's textual, because it's talking about more ideas than concrete specifications and numbers. You'll have, that's part of your data, right? You're gonna have data that's gonna tell you how the system's wired up and where all of the pieces fit together. But the actual code itself is not so much concerned with the concrete instances of how every individual component is wired up. It's concerned with the abstract way that the component behaves. And then if you create a thousand or 10,000 of them, you don't have to write that same code a thousand or 10,000 times. So one of the things that Dijkstra talks about is Dijkstra talks about how code and programming is a completely new type of intellectual activity. And he says that the roots of that are in scale, that it's the first thing that sort of covers many orders of magnitude, where you're both sort of doing bitwise operators and flipping bits down at the bitwise level in this extremely fine-grained detail. And then you're also streaming files on the order of megabytes and gigabytes and terabytes and doing map-reduced jobs over terabytes' worth of data. And we think, all right, that's not so weird, a bit's a bit and terabyte's a terabyte. But actually the difference in magnitude in terms of the material there is massive. So you could make the silly analogy to a building where it's like the contractor's both working, doing something very fine-grained to a grain of sand and then also building the skyscraper and that's the same job for the same guy. But he has a certain point. And so because of that he talks about how a new programmer should remove all of your preconceptions and approach programming in full humility with sort of a blank mind as because code is such a fundamentally new thing. So in terms of how Dijkstra might wanna have his ideal simple programming language, potentially for the web or for beginners, he idolizes a very interesting flavor for beginner programming and I'll quote from him here. So he says, we stress that the programmer's task is not just to write down a program, but that his main task is to give a formal proof that the program he proposes meets the equally formal functional specification. When designing proofs and programs hand in hand, the student gets ample opportunity to perfect his manipulative agility with a predicate calculus. Finally, in order to drive home the message that this introductory programming course is a course primarily in formal mathematics, we see to it that the programming language in question has not been implemented on campus. So the students are protected from the temptation to test their programs. So here Dijkstra is expounding an attitude that of an ideal programming course for beginners that is almost totally alien to maybe the way that we work where the programming language should not be implemented so that you're not tempted to actually test your programs because, of course, actually running them and testing them is a terribly fuzzy and ill-defined way to think about programming. And for him, it should be all sort of ivory tower in your head, conceptual, rigorous, proven, but not actual, not scribbling and sketching, not smudging around with ideas and not in the language and in the working out but in the mathematics and in the mind. So that's one attitude, a sort of opposite attitude is Mr. Nooth, who says that here, science is knowledge, we understand so well, we can teach it to a computer, and if we don't understand something, then it is an art to deal with it. And so when Nooth gave his Turing lecture, he talked about the art of computer programming and that computer programming should not be considered to be a science, should be considered to be an art or a craft because it's not something, it's something that takes a certain sort of sensibility and aesthetic to deal with and to design correctly and it's not, you can't reduce it down to mathematics and you can't reduce it down to a rule book of patterns and principles you should follow. So these are two sort of intellectual giants on the scene grappling with this notion of code as a new thing, a new artifact, a new substance to work with and how do we wrestle with it in a way that's gonna be productive? So for me, I think that the key thing about programming and the key thing about code that makes it so bizarre to work with and so interesting as a topic is that when you write code, it has a dual audience. So most types of writing and most types of language, they are expressed to many people but to a single audience. So when I'm talking right now in English, there's one way of understanding English and each person's gonna have their own slightly different interpretation based on how they hear and how they understand and their own personal experiences and their own meanings of the word but the way I'm trying to speak and the rhetoric that I'm using is designed to convey a certain particular bit of information in the language to a single audience but when you write code, you actually have two audiences. You don't just have one. You're writing for the machine to execute your program and you're also writing for human readers to be able to read and understand your code and you're doing both of those at the same time and you're not just doing one or just doing the other. If you were just writing for the machine, then all of our fancy, high level, highfalutin, C++ and Ruby and JavaScript scripting programming languages would not matter because if you're writing for the machine only, you could just use machine code and it wouldn't matter how easy it was to understand. It wouldn't matter if you were generating out these long strings of machine code looking like noise because if the machine ran it and that was your only audience and you never had to read it yourself or understand it or have someone else read it, that would be the optimal way of programming and the reverse is also true because the machine is the ultimate arbiter of if the code is actually code or not. If it actually works, if it actually runs. So if you just write for the reader and you don't care if your program is gonna be understandable by the machine then your code simply doesn't work. So it's this balancing act of addressing both audiences. You have to end sort of the history of the progression of programming languages, of programming languages starting out very low level and becoming more and more quote unquote high level but really what we're saying is that whereas before we addressed the microprocessor more directly, we talked to it in a language, in assembly, we talked to it in a language that was much closer to what it actually understands directly and now we're talking to it, we're shifting the way that we speak to address a little bit more to the reader and a little bit less to the microprocessor. So the program has to do a bit more work to catch up but the reader can understand things more clearly. And so it's interesting I think to look at sort of the progression of programming language through that lens as a shift of you're still talking to both at once but the way that you're addressing has moved a little bit over time and it'll perhaps continue to move in the context of JavaScript evolution as well. So it always feels a little bit silly to talk about the future of a programming language or the future of JavaScript because it's sort of wild speculation and we really don't know and I'm sure that what ends up killing JavaScript and replacing it will be vastly different from anything that we could think up on stage. But I think there's a few possible futures that are worth looking at. So one is a browser rule that the future of JavaScript will be handed down from the mountain by Microsoft or Apple or Google and it will be shipped in browsers, it will be codified and we won't have any say in the matter and that'll be that, it might look very familiar to other programming languages, Google might say, oh, everyone in school learns Java so let's make something that looks a lot like Java and that will be the future of JavaScript and that will be that. We'll ship it in Chrome, everyone will use it, it'll be fast, it'll be great. And there's another possible future which is more like a Tower of Babel type situation where right now we're all working on this shared edifice that is the web and that is programming on the web and we're all speaking the same language right now but there'll be some sort of crack in the building and suddenly there'll be a little fragment into a multitude of competing dialects where people program in their own style and it all works fine and they can still get their job done which I think is a more exciting possibility. So CoffeeScript is one dialect like that and the whole notion of programming in the browser or in JavaScript but in a language that was not quite JavaScript used to be a lot crazier of an idea a few years ago than it is today which I think is pretty cool but despite sort of talk about how wild and crazy it is to be using something like CoffeeScript it's actually a very conservative and extremely conservative approach. So because of what I explained before about keeping close to JavaScript semantics and not really getting too far away from them where something like ClosureScript is much more radical. So but what if we were gonna take some of the same ideas that go into CoffeeScript? Sort of the idea that we wanna be boiling this language down to its minimal essence and making it easy to read and making it conceptually easy for beginners to understand sort of get this basic minimalist programming language that's not, doesn't have every feature under the sun but just the essential features where and but we weren't gonna be conservative if we were gonna be radical about it where might we start? So I think one of the best places to start with is this foundation of right now you wanna work for the web, you wanna program for the web you have to deal with hypertext markup language and this other language called cascading style sheets and this other language called JavaScript and if you're a beginner that's already daunting, right? You've already got these three totally different things you need to learn how to use and there are three different languages they've got different grammars they've got different escaping rules they've got different syntaxes for the same types of things but what we're really talking about here is you have your document, you have your structure it is a tree of data a big tree of data with sort of usually text as the values but in an application it could be different things you've got these maps, these hashes these dictionaries of key value pairs where the value is a style and the key is a pointer into your data, right? So you've got these trees, you've got these maps and then you also have finally a real Turing complete programming language a real scripting language that glues it together but there's really no reason why you shouldn't or you can't have one language that does these things, you know? We talk about separation of concerns and all that stuff but really it's sort of it's a justification, self-rationalization after the fact, right? It's an accent of history that we ended up with three languages and now we have to rationalize why that's a good thing instead of thinking about how funny that is that you'd have a whole different language just to talk about trees that have text in them and you'd have a whole different language just to talk about styles that point back to places in that tree. It's really an accent of history and I think it'd be very productive to think about in terms of your own thoughts about the future of JavaScript, what it would look like to have a single language that has a very good syntax and a very good support for tree data structure that is document-like and a very good support for pointing into that tree with key value pairs and assigning properties to specific places in that tree and also be a general-purpose programming language that's good to work with on its own and if you can imagine a language that looks like that I think you're coming closer to imagining the future of JavaScript. So the last thing I think I wanna say is that all this stuff is pretty exciting and it's exciting because we're still dealing with programming languages, right? We're not dealing with Photoshop style or an AutoCAD-like programming tool where we're just wiring up boxes and fiddling with sliders and designing our program in that way. We're still using text, we're still using words and I think that's really amazing and if any industry should have been revolutionized by computer-assisted design, as an industry it should have been programming it should have happened 10 or 20 or 30 years ago that you would start to program computers not by typing in text that you can print out, not by typing in text that's like an essay to the machine about what you want it to do but it should have been the case that 20 or 30 years ago someone designed some super programming studio plus plus where you'd have all the boxes for your objects and you'd wire it together and that would be how programming was done but that didn't happen and I think it's very hopeful that it didn't happen because it tells you something about the nature of programming that it's not so close to engineering in the sense of putting together a system composing together a system out of boxes and it's more about dealing with ideas and conveying ideas to your fellow programmers who you're working with and conveying ideas to the machine expressing new ideas to the machine the machine didn't know how to do before and I think that the fact that it's text is something to appreciate and to applaud and so on that note, thank you very much thanks for having me and I think there'll be a few minutes for questions. Hi. First of all, thanks for creating CoffeeScript, it's great. You're welcome. We have been reading articles that are not super reassuring about the future of CoffeeScript specifically related to ES6 so people are writing stuff like by using CoffeeScript, you are locking yourself into always using ES5. Right. So can you talk? Not even ES5, ES3. Okay. But sure, so where my perspective is and where CoffeeScript comes from is and I think a lot of programming should think about is we have this problem in software but also in open source with vaporware and I'm not trying to say that ES5 or ES6 is vaporware but in my world you have to write code that works on machines that people use so that includes, it included previously IE7 and IE6 and it still includes today IE8 because there's a whole bunch of Windows XP machines out there that are never gonna get upgraded to IE9 and so the most important thing is to have a tool that will not force you to do workarounds if you wanna make your code run across the board and so for that reason CoffeeScript takes these things that are in ES5 and ES6 and compiles it down to lowest common denominator ES3 so it's in a way that it's compatible. And now, so for going forward, the concern is that ES6 will introduce features that already exist in CoffeeScript or that are in conflict with CoffeeScript features and so the code will suddenly not work correctly. So the first thing is that because CoffeeScript targets ES3 it will always generate code that will run in browsers and it will always continue to be forward and backward compatible because it sort of works today so just because ES6 has a new class keyword that doesn't mean that CoffeeScript classes break or they stop working, you know what I mean? That still will continue to work just fine. The issue is whether we wanna end up adopting ES6 features into CoffeeScript instead of doing our own fall black implementation and I think the answer to that question is that you absolutely do wanna do that at the point when that feature is actually supported across all the browsers that people use. So it still is totally hypothetical because you don't have classes that you can use today across all the browsers that are compatible. You have it working with a certain flag and node, you know, under some circumstances but it's not something you'd wanna ship in code that has to be reused across the board. So when we get to that point where you can fall back on things like that I think that's something that's worth doing and there are a few features already like yield and generators that we should be adding now because they're not that type of thing that have conflicts but so that's sort of the approach. So once it is supported across the board then we can talk about using that as the implementation underneath the hood but until that happens it's sort of, it's still, you know what I mean? For the last 10 years you've been working with the JavaScript that you can't even rely on index of existing on an array because in IE7 and IE8 there is no index of on an array and we're still like that today. So for me it still hasn't changed fundamentally what you can do one bit. Maybe we'll get there soon, hopefully we will. Awesome, thank you very much. Thanks.