 Buenos dias. Did I say that right? I hope. How are we doing? Okay. Inventing the future. We live in a really interesting time for JavaScript, and at least I think it's interesting, and I'm kind of excited about it. And my goal here today is to share some of my excitement with you. So I'm told you can get remotes and things like that, but I'm old school. I actually go back to when people had actual physical slides in a carousel, so don't mind me as I wander back and forth. What I'm going to talk about today is the fact that we're at a time when JavaScript is about to have a serious bit of evolution. I'm not the only person talking about this. And I think it's kind of neat, because unlike programming languages of the past, which were designed, you know, by a few people in a university or something, and then sort of launched, we're now in a place where programming languages are crowdsourced. Many of the features coming to ES6 come because we, the users, complained and said that we wanted stuff. So the purpose of my talk today is to talk about some of the things I think we could be complaining about for ES7, basically. So JavaScript is a very old language in some ways. Its roots go back to the late 60s and 70s when you look at what inspired Brent and Ike to create JavaScript. And that's good in some ways, because many of those ideas were great ideas. However, time marches on, and we must march with it. And JavaScript has not marched on as well as it could have, and I argue it hasn't really embraced all of the older ideas as well as it could have, which is not a bad thing. Does anyone here know that JavaScript was originally invented as a server-side language, and the idea was to use Java in clients? So, you know, things have changed since it was first invented. And this is where we should be going. We should be able to take what was old and good, and expand into what is new, and also good, but good in a different way. And if you'd like to come visit me, that's the Royal Ontario Museum in Toronto, and I'd be delighted to go there with you. Let's start by looking at some of my influences. Oh, JavaScript's influences. I think I put this slide in here for Ross. You can probably name all three of them in that picture very easily. So, let's go back to when Reg was young, and Star Wars was something you went to a theatre to see for the first time. Here's a gentleman that some of the Spanish cycling fans will recognize, a great cyclist in his own right, and the best programming language in the world at that time, and many people argue still for some reason, was Lisp. And the idea that JavaScript stole, as everybody knows, at least everyone who's heard of JavaScript, the good parts, was first-class functions. And the functions were originally actually invented by an Iranian gentleman. I will not attempt to mangle his name, or discover it, I suppose, since they're an underlying truth. And I think, does everybody embrace the idea that JavaScript fundamentally is built out of functions? Everything you do, making classes and so on, methods are actually functions. Everything's a function. And one of the neat things about that is that you can write functions that transform functions. Now, it's kind of obvious you can write a function that takes a function as an argument and returns a function. And in theory, you could take a function, say, that adds two numbers together, and return a function that's correct spelling. That's theoretically possible. But what I mean by transforming is that you take a function, and you return a function that is similar to the original function, but is different in some way, like making it taller or shorter. That's not a good example. Perhaps you could take a function that sorts alphabetically and return a function that sorts numerically or something. The examples I give, once memoized and maybe, are all things you can find in popular libraries. Once, for example, takes a function, and returns a function that does what the original function did, but it only does it once. If you call it repeatedly, it doesn't do anything the second, third, fourth time. So here's a crazy idea. If your function is supposed to process a transaction, you know, instead of really spending a lot of time making sure that you never call that one twice, you could just wrap it in once and then not worry about it. Memoized does a similar thing. You can call it as many times as you want, but it only actually does the work the first time. And maybe is used for checking if something is undefined or not. If the argument is undefined or not, it just returns undefined or not. It takes a function and then turns it into another function that does a similar thing with a twist. Now, in addition to being able to use functions to transform functions, this idea of functions as first class objects that JavaScript gets from Lisp also takes into account the idea of composing functions. Now, this is a bit confusing because there is in fact a function called compose. But the general idea of composing functions is that you take two functions and you put them together in a way that retains the characteristic of both functions. So a very easy example is before. Take two functions and return a function that evaluates the first function, then evaluates the second function. After it does the same thing, only reverses them. Begin one and begin to do similar things but with lists of functions. They compose a new function out of the pieces of the old function. Compose does a similar thing with different argument orders. But the whole idea is that you have functions that take other functions and return functions. Now, I kept saying that these transformations or these compositions retain the character of the original functions. And that's important because if we look at a program, say that does banking, you're going to find some functions that are in the banking domain. They put money in an account or return a balance. And then you'll have functions that are not in the banking domain. They're cross cutting concerns, you could say if you're feeling very enterprising. Things like before, after. They're general purpose functions. And if you think of them very explicitly in these two piles, general purpose functions and functions in the sort of the programs domain, and you also have a little interest in math, you come up with something called a semi group. A semi group is a set of some kind. Since we're talking about functions, a set of functions, and an operation or a set of operations on those functions, and the key is the operation takes some of those functions and returns another function that's in the same set. My head hurts just saying that. So when we talk about something like before a function that takes two functions, then executes them in order or compose or after, those form a semi group with the functions in the domain. For example, if you have withdrawal from an account as a function and deposit to a different account as a second function and you combine them together, the result withdrawing from one function and depositing to another is still in the program domain. It's still a banking function. You haven't turned it from adding two numbers into a spelling checker. And this general idea that we can take some functions in our domain and then combine them to create another function in our domain that does something, has this complicated name, but more importantly, it has a really interesting consequence, which is that it makes it really easy if you design your program in this way to take little bits and pieces and put them together in different ways. For technicians, here's an example. Addition, if you add two numbers, you get another number. And another property for people who are into math is associativity. Whether you add them all together or add two and then the third or take the first and add it to the sum of the second, it all comes to the same thing. Any time something has these properties, namely that it takes two things in the domain and produces another one in the domain, namely that it has this associativity property, for example, begin has this or before has this, it makes it really easy to put together programs where you know what's going to happen. It makes it really easy to understand that there aren't some special side effects you don't have to worry about. When you just cram functions together willy nilly, you have a situation where if you decide later to rearrange them or insert another one in, make changes to code, you have to test everything, you have some uncertainty as to how it's going to work. Being able to build things in this kind of structured way allows you to reason about your programs and to write better programs. Now, all of that is just sort of airy fairy things. But here's the consequence. If you write programs in this manner, it's very easy to keep the pieces separate, to test them separately, to reuse them in a different way. This is something that isn't designed into JavaScript. It's something that arises from the properties of JavaScript in a natural way, provided we look for it and take advantage of it. I bring this up because when we look at where JavaScript came from, and then we look at something like this, if we said ES7 should make it easier to build programs in this style of composing functions, we wouldn't be saying, here's a new idea we stole from Haskell. We would be saying, here's an idea that was always there. Now we're just going to do it in a regular way. Now we're just going to do it in a more powerful way. This is something that's already there. We just need to pay attention to it. In the 80s, when this gentleman was stomping around the hills, this was the most interesting language in the universe. Well, possibly not, but certainly as far as JavaScript is concerned. This was the language that really sort of brought the idea of objects in encapsulation to the forefront. Now I think we all know what encapsulation is. No matter how complicated the bits are inside, from the outside, all you see are two hands that move, and I see sort of a plug and a winder on this, and there might be two things you can push in a winder. So there's a limited sort of interface from the outside, but the inside can be as complicated or as simple as you like. I understand that you can buy a Rolex, and it has a bunch of mechanisms like this, or if you go to certain types of malls, shopping places, you can buy something that looks like a Rolex, but if we open it up, there's some sort of quartz electronic movement inside. But from the outside, they both look like a Rolex. Encapsulation is very, very powerful because it has the similar property to what I mentioned earlier with this high-flute and word about semi-groups. When you have objects that have a very small interface to the outside world, it's easier to recombine them in different ways. The same idea is functions that you can combine them in different ways, objects can be combined in different ways. When you don't have encapsulation, when objects reach in and play with each other's interstate and so on, you cannot recombine them in new ways. They become very calcified, they become coupled. Unfortunately, even though we stole some ideas from small talk, encapsulation was not one of them. JavaScript resists encapsulation. You have to go out of your way to create encapsulation in JavaScript. Everything's public. This is an area when we're thinking about new directions to go, not just with the language, but with our programs, where we could pay some more attention to where JavaScript came from, to what we copied, to making sure that we get the, that it's not just that we use JavaScript the good parts, but when we think about how JavaScript learned from other languages, we use their good parts too. That's a tremendously egotistical thing. I'm about to talk about what small talk got wrong. Not a good idea. This was another, besides encapsulation, another primary tenet of small talk. Now, when Alan Kay and his colleagues invented, discovered, codified the idea of class hierarchies, of subclasses, they actually thought that these would not be used by everyday programmers. Their plan was that professionals would design class hierarchies, such as the one that's numbers and magnitudes in small talk is a brilliant class hierarchy. They thought that these things would be designed very carefully, very, very carefully, and then other people would use them and maybe extend off the bits of them, but they did not think that when you're building a banking app, that you spend a lot of time deciding that there's a checking, that there are accounts, and that some accounts are checking accounts, and some checking accounts are US dollar checking accounts, and some checking accounts are Euro checking accounts, and some checking accounts have fees, and some don't. They did not think that everyday programmers would spend a lot of time building class hierarchies, so they designed a tool essentially for professionals. Unfortunately, that's not how it turned out. People do design their own class hierarchies, and it's usually a pain, because once you get started, you wind up with these pyramids with a base class at the top, like object, and a bunch of stuff depending on it. The problem is that specialization, which is the fundamental idea behind using classes, or delegation with prototypes in JavaScript, specialization and encapsulation are kind of opposites. Specialization, as it's designed in most programming languages, and as it's practiced in JavaScript in the wild, involves classes that have, or prototypes in JavaScript, that have intimate knowledge of the interstate of the objects that extend them. When you write a prototype, you can modify any property of the object that delegates to that prototype, and if you have a chain of prototypes, they all can modify the same set of states, so they all become tightly coupled. They're not encapsulated from each other. Every class in the hierarchy ends up having a dependence, and a deep dependence, not a dependence on the methods of, but a deep dependence on the state changes, the properties that can be changed, of the objects in the, sorry, of the prototypes that are higher up in the chain. So you end up with something, just skip right over that, called the fragile base classes. The higher up a class is in the chain, the more stuff depends on it in a very messy non-encapsulated way. So we go out of our way to make object-oriented programs that have these nice encapsulated APIs for objects, and then the minute we start playing around with prototypes and classes, we reverse all of that and have everything just putting its hands in and mucking about. So that is something, I said small talk got wrong, that is something the world got wrong, this over dependence on it, and it would in fact be about 15 years later when people started popularizing patterns, that people started saying, ah, prefer composition to inheritance. People started to realize that inheritance is in fact an anti- pattern most of the time. It's to be used when you have no alternative, not as the first recourse. And when thinking about where we want to take JavaScript programs that we write, or the language that evolves from us expressing what we want from the language, we have to think about the fact that what small talk got wrong should not be the focus of where we evolve JavaScript. We should evolve away from that just as small talkers, if you find a professional small talker now, they've moved away from these things. Why should we copy their mistakes when we can copy the things that they got right? And then as a bonus, here's another thing small talk got wrong. Show of hands, how many people are familiar with the expression problem? Not enough. So the expression problem is very simple. We're writing a drawing tool, and we have pens, pencils, and so on, which we model as objects that have methods, draw, lift, display, a tool tip, display, an icon, you know, there's a whole set of behaviors for them. A standard kind of class oriented architecture makes it very easy to add a new tool. You want to add a brush, you just have to implement these methods, and then you extend some sort of prototype that has built in stuff, or you don't, and it just works. As long as it implements the same methods and has the same semantics, you can add a new tool. However, let's say we decide, oh, our drawing program should be collaborative in real time, so we're going to have to add some new methods, for example, to display over the network to somebody else, perhaps. I'm making this up as I go along, so don't take it too literally, but we need to add new behavior. Now it's not so easy. Now we have to, we have to go into every single class that implements every single tool and add new methods to it. The expression problem is that there's really two axes that need to be designed. Behavior and entities, and programming languages tend to make one easy at the expense of the other. Object-oriented languages that involve delegating to classes tend to make adding new entities easy at the expense of changing behavior where you have to go across a lot of, a lot of things and change their behavior, and that's the expression problem. Smalltalk doesn't have a great solution for it. I'm not going to give you a solution, but I would say that if you're aware of the problem and you think about it when you're programming, maybe you can come up with some good solutions for it, and if those become popular, some future version of JavaScript may bake those in. That's, that's how promises got in, that's how let got in, that's how fat arrows got in. People got so excited about it, they wrote entirely new programming languages that transpiled to JavaScript just so that they could have it, and then it got into the language. In the 90s, this fellow was dominating everything, Miguel Indurain. It's funny, does everyone see the, the theme of the cyclists that I'm showing? No, I guess it's not as clever as I thought it was. This was the programming language of choice. I was there, it's true. A programming language that gave you everything. You want to go in the water, it goes in the water. You want to drive on land, it drives on land. Actually, if it was C++ for real, it would have jet packs, it would have helicopters, you could do everything, and in a way nothing, because they were so hardcore about don't pay for what you don't need, that when you do need something, it's always really convoluted to do it. And this is the takeaway of what C++ got wrong. Unfortunately, it's something that Java copied. We copied the Algal syntax, the little braces, the fours, the wiles, the whatever. And syntax is something that helps languages be very approachable when you first learn them. It's nice to be able to see the difference between an if and a four at a glance, as opposed to have to read a keyword and understand what it, not to read a keyword, but as opposed to having to have something that a programmer defines or is a macro or something. However, syntax, its benefit is that it's standardized across everything, but the horrible part about it is that it is baked into the language in such a rigid way that all of the things that we can do with stuff like functions or objects, we can't do with the syntax in our language. Smalltalk, for example, had an idea of blocks, which are objects, and you can do anything with a block in Smalltalk that you can do with an object. Ruby has a similar idea with and unfortunately JavaScript does not. You can't take a function and reach inside of it and take a piece out. Now, I'm not suggesting that some future version of JavaScript should look like this. However, we should be aware that as we add new syntax to the language, we are slowly calcifying it, we are slowly making it harder and harder to make changes. Even now, when they're worrying about all sorts of new keywords and ideas and promises and things, they always have to sit there and say, is that backward compatible? Will it work with the parser? The syntax is there in place, is actually getting in the way. And meanwhile, new ideas we have, like promises, don't need syntax. People try sometimes to invent new languages that will somehow implement them with syntax, but fundamentally, they're not about syntax, they're about semantics. So I believe that in terms of inventing the future, we want to get away from special purpose syntax. Let's move forward in time a bit more to Alberto Contador, who's still racing today. And this fellow was standing right here last September. And this is how I feel about Ruby the language. It has everything in a much better way than C++ has everything, but it still has everything. And what people love about it is that they can write domain-specific languages. They can write stuff that's supposedly very easy to read. However, optimizing for being easy to read sometimes means that when you look at the implementation, it's really terrible. Behind the scenes, a lot of these testing frameworks and so on are incredibly ugly. And they're leaky abstractions. You really have to, as much as it looks really easy, you can't just do anything in them. If you actually start writing things in a different way, you kind of have to understand what the exact model is that makes it so easy to read. It can be helpful when you're writing things that need to be read by non-professionals, but actually is a bit of a trap if you're writing things for other professionals, because it ends up being more of a pain. And so I kind of feel like language features, like key words and so on, are a kind of technical debt. They give you something today, but down the road, you end up paying for them in terms of the inflexibility of the language and its features as you try to move things along. And I think we all know this. It's a problem with JavaScript. We copied this from other languages, and we pay for it. Everything becomes dependency management nightmare. Trying to keep track of, well, you have this module, and it has to be this version, and that module has to be that version. And how do the two mix if you can't upgrade? We copied these nightmares, almost line for line, and we could do better in the future. I think we should do better. So let's talk about now. Oh, there's a cheerful looking fellow. Looks happy. So I took earlier about semi-groups, this complicated word. It's not a complicated idea. It's just mathematicians, you know, they're technicians. They like to have very specific words that mean very specific things, but it's not a complicated idea. The idea of things, be they functions or objects, be it a bank account or an interface or a class, the idea that we can compose them or transform them, they require encapsulation. If you don't have encapsulation, it's very, very hard to compose things. If you have two things and they both muck, say, with global state, you can't decide, well, I'm going to do A and then B, and then a little later in a program, decide I'm going to do B and then A, because they both mess with state in a certain way. In order to program in this style, while all of your pieces can be composed and transformed, you have to make sure that things are actually encapsulated. And I think it's easy to find examples, you look at programming languages like Haskell and so on, where people have done a lot of work with functions in this matter, with making monoids in Haskell. But not as much work with objects, because object-oriented programming has historically been in a different branch of the programming language tree from the functional programmer. But the idea works just as well with objects. When people talk about composition, it's not just has as we're going to make an object and it has little parts inside of it, but the idea, say, of using mixins, where you have behavior from one part and behavior from another and you mix them together, that's a form of composition too. And all those things are possible with objects, provided you design them to be transformable, composable, encapsulated, and you get decoupled for free. And I mentioned the idea with mixins. As it is now, the primary dominant way of writing made objects of designing behavior is with prototypes and prototype chains. And this is a highly coupled way of combining things. And it becomes highly static. And when you have a big, I don't know if you've ever tried refactoring some huge legacy Java app, I have, I used to work in banking. Those those big trees, those big class hierarchies are highly coupled, as much as people use patterns all over the place. They're hard to refactor even with tools. And being able to work with smaller composable parts saves you so much of this headache. However, implementing it is hard. For example, it's only a couple of lines of code to write something that will blend two behaviors together into an object. However, if you say, yes, but I'd like to blend two behaviors into an object that I will use as a prototype for another object and still have them decoupled, then it becomes complicated. Then you have to have some place if they do have state, you have to keep the state for each of those two separate, and you have to somehow save it. If it's going to be used as a prototype, you have to save it separately with each object. So maybe you create a property that has a name that you can't see and you make sure it's not enumerable and it's because there's a lot of nightmare in the implementation. This is a place where the language could help us a great deal. But it's only going to do that if we actually get out and start doing the things ourselves and then demand help from the language. One of the easiest ways to avoid me standing up here and talking about a word like semi groups is if we all get out of our comfort zone and learn some other programming languages. As long as we focus on our tool at hand, we become really, really good at doing what we were already doing with it. The way to get really, really good at doing something else with our tool is to become familiar with other tools. So get out, learn some Haskell. While you're at it, learn a programming language that's really, really good at taking objects and transforming them. Not just the language in terms of its features, but the community itself. Learn some closure. I talked about composable meta objects. This is not something I made up. These are things that are in languages like Scala and Go now. Go out, do some work with them. Read a little bit about them and then bring that back to JavaScript. Bring those ideas. JavaScript has already copied from Lisp, Smalltalk, C++ and Ruby. Go forth, get ideas from other languages and let's use them. We're kind of at a neat time. Speaking of time, how are we doing for time? Does anyone know? I have no idea. Nobody knows. There we are. So let's wrap up. JavaScript is kind of a neat language in that I think of it as a blank canvas. It doesn't actually have classes. However, it has things you can use to build classes. It doesn't have mixins, but it has things you can use to build mixins. Now, if I say that JavaScript is a meta-object one language, but you can build meta-object twos, I'd be using jargon again. Ruby, how many people here use Ruby? Right. So Ruby is a meta-object two language. In that, it's meta-objects, classes and modules. They have methods, but they're not the methods that they confer upon objects that extend or use them. Right? It has a method like methods that gives a list of methods. The actual methods you'd get by implementing that class, of course, would be a different set. There's two kind of worlds going on in a Ruby class or a Ruby module. The methods and behavior it confers and the methods and behavior it has as an object. Small talk works the same way. JavaScript and Python are meta-object one languages. The methods of a prototype are the methods that it confers upon something that delegates to it. So, getting back to what I said, this is not a feature of JavaScript made of object twos, but you can build them. Everything's like that. Promises are not a feature of JavaScript, but people just built them. So, I think, as we go forward, the idea is to keep JavaScript small in that way. We talked last night at the speaker's dinner about good magic and bad magic. I like magic. But bad magic is kind of a leaky abstraction. It kind of like works really well in the demo or for this specific thing. It has a complicated implementation behind the scenes, a lot of code. Good magic is like, did you know a couple of lines of code in this wonderful thing happens? Good magic kind of arises naturally from the capabilities of the language. The canonical example would be the way that closures work in JavaScript. This is not some magical thing that involves a lot of implementation to get a function that gets some state from the function that created it. It just arises naturally from the way lexical scope works in JavaScript. It's very good magic. As JavaScript moves forward, I would like to see us keep that nature of JavaScript, that there's a few things that happen to work together and then wonderful things arise naturally from those small parts. And I'd like to see this be our philosophy in the community that we don't look back and say, you know what? We copied classes in ES6 with the class keyword but we left all of these things out that are in Ruby. I don't think we should be that way. I think we should look back, understand it, see what the good parts are but we shouldn't sort of bend ourselves to trying to catch up to what languages we're doing 40 years ago. I mean, really, we have this opportunity. Why don't we look at languages that are new now, that are doing great things now, not languages that were great when I was in high school? We should be looking at Haskell closure, Scala, we should be saying what are these people doing? What's happening with in these other areas? And I know, I keep talking as if everybody here is designing the next version of JavaScript but you are. This is very community driven language. Things that were in jQuery are now a standard sort of way of doing things and may one day become a standard part of the language itself. Our language evolves as we evolve our programs. So it is our responsibility. And so I asked you to ask yourself, I've told you what JavaScript copied from 40 years ago or from 30 years ago or from 20 years ago or from 10 years ago. What will people copy from JavaScript 10 years from now? If the answer is nothing because we're just copying stuff from 10 years ago, that is an unacceptable answer. We're wasting our lives. What will people copy from us 10 years from now? What will people copy from us 20 years from now? What idea is somebody 10 years from now maybe someone who isn't even born today is designing a new programming language and they'll say, I've got to steal this from JavaScript. That's what we should be inventing today. And with that, I'm done. Gracias. The question was, what do you think about the kind of metaprogramming you can do with a Lisp? Yes. So the question is, what about having a small kernel and then you use macros in order to develop more things on top of that? That is an excellent question. So it sort of touches on the question of should there be syntactic sugar such as the class keyword, which is very different than a feature like a co-routine which cannot be implemented in a macro. And generally, you know, people sometimes say, oh such and such is just syntactic sugar. So the definition of kind of syntactic sugar is can something be done with local transformations like a macro or by parsing the language and changing something or does something require a more global change to a program? Something like, so something like continuations, for example, cannot be implemented with macros. That involves changing the way every single function call and method call works. Something like changing the behavior of the this keyword would involve, if you wanted to do it with, you couldn't do it with macros. You'd have to change the way every single thing function call and method call worked. So I love Lisp and I love macros. However, I recognize, I think that there are some limitations in that some of the ideas that are really exciting. For example, I didn't mention it, but a really fertile area in the future is things like the this keyword. How does it work? Making it work a different way. And so, I would say it would be limited to only do that because you can only make local changes. For example, you could create your own class keyword or create your own mix-in keyword or some more traits and things. Those are very easy to do with macros, but there are other features co-routines, generators, and so on yield keyword that are not amenable just to the macro. So other work would still have to be done. Is that an answer to your question? Okay. To our next question? Yeah. Thank you for that. There's a mic coming just behind you now as well. You've all a passionate plea to keep the core language small in a sense you would argue that you've already lost because ES6 is ES4 reincarnated and I don't see it improving in the near future. There will be more syntax. There will be more constructs. There will be more convoluted artifacts introduced to the language. So isn't the possible escape the concept of JavaScript as the assembly language being used to, for example, languages like closed script or Faye or whatever thing you'd argue for and what the sense of source maps that could be a possible future? Yes. And that's a really interesting future. You'll hear from Jeremy tomorrow about JS Next and CoffeeScript. I'm a big enthusiast. I think that when it comes to JavaScript being the assembly language though you don't need ES6 for JavaScript to be the assembly language. As a matter of fact, Mozilla has something. I'm sorry. I've only had one coffee this morning. I cannot remember off the top of my head, but they have a subset of JavaScript that's designed specifically as a compilation target. ASMVGS. That's the one. And so you don't really need anything else. You can just compile to that. I think it's a very valid strategy to have a completely different language that compiles to JavaScript. I was speaking to improving JavaScript as a language that we write programs in but writing a new programming language is the ultimate form of programming. So I like that too. I like that as well. You should probably listen to some fellow who's going to talk about closure script, I think, at this very conference. There was a lot of that in C Sharp as well and they introduced things like Link into C Sharp and suddenly you had built within the language almost another language that was compiling down to the language. That's a lot of... One more question? Do we have another question? No. That's great. All right. Thank you very much, Edgernal. Thank you very much.