 Welcome to the presentation, Elixir and the Browser. My name is Brian Joseph. You can find me on GitHub, Twitter, on the Elixir Lane IRC channel as Brian JOS. That's the name Google gave me a long time ago, so it just kind of stuck. A couple of facts about me. I'm born, raised and still located in New Orleans. I created the New Orleans open source hackathon two years ago now, so this year was the second year. It's such a success that people convince me to do it bi-annually, but it's October and I haven't started planning it, so I don't think that's going to happen. I volunteer for an organization in New Orleans called Operation Spark, which tries to encourage at-risk youth in New Orleans to start programming. And I began programming Elixir in late 2013. I was looking at it in that summer, but after programming Elixir by Dave Thomas, I got hooked and actually started working within it. So this presentation is on Elixir Script. And Elixir Script is an Elixir to JavaScript compiler. The goals of the project are to translate a full or subset of Elixir to JavaScript. What that means is, try to get as much as possible, but if there are some things that don't really map over, then we won't worry about those things. We target ES 2015, so the latest version of the Elixir Script standard. Compliment Elixir back in, so we all love writing in Elixir, and the goal here is to come up with disciplined ways to talk back to Elixir back ends, and that might not necessarily mean using Rester JSON. Idiomatic, so when you're writing in Elixir Script, you wanted to look and feel like you're writing actual Elixir code, and to embrace the environment, and more on that later. So why Elixir Script? Because JavaScript is tolerable to put it best. So all the way up until recently with ES 2015, which is better known as ES6, even though JavaScript has become the most popular programming language, basically, the language itself hasn't really been updated until ES6 has come along. And I think, I don't know, to me it's not the greatest language in the world, but on top of that, I think it also has, because we're kind of stuck with using it in the browser, I think that also helps with some of the connotation of why people don't really like writing in JavaScript. On the other hand, Elixir is awesome, like I want to write everything that I can in Elixir. I was going to make a joke about wanting to write a long war using Elixir, but I was listening to the Turing Incomplete podcast recently, and one of the co-hosts is doing exactly that. And it's also been a fun and interesting challenge. So going from translating a language that is built for the Beam VM and translating that over to the JavaScript virtual machines is not exactly an easy thing to do. And what I've tried to do is treat it like a puzzle and keep it fun and engaging so that I can make some progress on the project. So how did all this get started? It happened around February, so I was reading, so Chris record's book Meta-Programming Elixir came out, and I started reading it. At this point, I was using Elixir for a little bit over a year, and I didn't use, I wasn't using Macros much at all. So that's why I picked up the book. And one thing that I immediately saw is that the Elixir abstract syntax tree is available without much fuss for anybody to use. At the same time, for either this reason or another reason, I'm not sure, I was looking at the SpiderMonkey abstract syntax tree. So SpiderMonkey is a virtual machine, the JavaScript virtual machine for Firefox. And they have a parser API specifically for it, which defines all of the nodes within the SpiderMonkey AST. And this AST is the basis for the ES tree spec, which is a specification around a JavaScript AST, because there's multiple JavaScript ASTs, a specification around the JavaScript AST that a lot of tools can use. So for instance, Esprima and Eskogen, and also I had five days off from Mardi Gras, so instead of partying, well, I'm not a partier anyway. So I just kind of stayed at home and started experimenting, and the first thing I did was create the ES tree library. And what this does is it's an Elixir library that has structs for each of the JavaScript nodes defined in the ES tree spec, all the way up to ES6. There are some experimental nodes in the ES tree spec right now for async and await, and I could probably add those in now, but I'm not going to just yet. It also has a builder module, which basically just has functions that make it easier to build up in the AST, so it has a function for each of the nodes. And later on on the line, I added in a generator module, and the reason I added this is because the first versions of Elixir script, what it did was it built up the abstract syntax tree, it turned that into JSON, and then it drew that JSON over to a node process which was running as Kojen, as Kojen would turn it into JavaScript code, and then derive that goal defense to Elixir script compiler. The problem was that was a very timely process, so one of the examples I'm going to show when I was doing it this way, it took, it's not even a lot of files, it's like maybe six files, so it took like 20 seconds, I was like, this is not acceptable, so I created a small generator module that just takes the abstract syntax tree, generate it, and turns that into JavaScript code. And this is just an example of what the code would look like. So here I'm importing the builder and the generator, and the first thing I'm doing is I'm building an array, and it just has a one and the A, basically a variable, and the second part of this is the generate function from the generator module, and it takes that JavaScript AST and turns it into a JavaScript array. And this is a separate, a totally separate library, so if you need to use it for anything, it's available for use. Next up is Elixir script. So Elixir script is basically comprised of two parts, so there's the compiler itself, which is written in Elixir, and then there's a runtime, which is in JavaScript. So what the compiler does is, the first thing it does is it takes in Elixir code, either in its regular form as files are in the quoted form, and if it's not in the quoted form, it turns it into the quoted form. It then turns that into, it translates the Elixir AST into the JavaScript AST using basically the ES3 modules, structs that we went over earlier. It then turns that into JavaScript. And here's an example of how some of the basic data types are translated over. So you see here that numbers, basically integers and floats, they translate over pretty easily to JavaScript numbers. Binarys, they're translated over to JavaScript strings. Atoms are translated over to symbols, specifically using symbol.4. So what that does, it creates basically a global symbol using that description. And that's used that way so that when you're comparing atoms, then you can, then it should return true. Otherwise, all symbols are unique, so that's why it's done like that. And for the rest of these, object.freeze is used on them so that you can't change the values of any of those. So an Elixir list turns into a JavaScript array, a map turns into a JavaScript object. And you can see here another reason why atoms are translated into symbols is that with ES6 you can use atoms as keys within objects. There's a tuple class within the Elixir script library that is what's used to translate over to a tuple. And then bit strings, which were kind of a pain to translate over. But it's basically a class that just takes a list of objects, and so you not only have what bit strings, not only the value, you also have possibly types in the sizes. So this makes it easy to translate those over. This is the only thing that actually I haven't figured out how to do pattern matching on yet because of the effectiveness types in their sizes. So functions, so in Elixir we have functions where you have multiple arities, and for each of the arities you can have pattern matched versions of each of those. In JavaScript functions there's basically just one kind, and it takes parameters and the parameters that you add to a function are kind of like suggested parameters because when you call a function you can just put in as little or as many parameters that you want to. Because it depends on if the function recognizes those. So originally Elixir script was using a library, a fork of a library called FUNSI. And FUNSI is a JavaScript library that does pattern matching with JavaScript types. The problem was that I had to, what I did was I forked it and I started changing things and I realized at some point that there was, I was changing basically the actual like implementations of a lot of things. So I created a custom pattern matching library within script itself that better handles the types of patterns that you get within Elixir. So here you see that these four Elixir functions turn into, it uses a patterns.defmatch function which takes a bunch of cases and each of the cases have a pattern, it has three parameters. There's a pattern, there's a function you want to call, and then the third parameter will be a guard if there is one. So if the pattern matches and the guard is true then it will actually implement, actually execute the function. And here's a better example with actual patterns that you can kind of tell how things match over. So modules, one of the things that the compiler does as the very first step is it goes through the code and it figures out what, it finds all of the modules and stores those somewhere along with all of the functions and macros within that module and what this is useful for is specifically with imports in Elixir and JavaScript when you're importing something using an ES6 module you have to specifically define what you're trying to import which doesn't really map well to the actual import statements within Elixir. So this way mapping, getting a list of all the functions, we can support that here. So alias and import and require kind of work, I mean they work but you have to have them at the out of scope and require it isn't really at macros yet. And so those are for the Elixir modules themselves and what I ended up doing was adding a special import for a JavaScript module, so it was a js.import macro that takes two arguments basically. So the first one is either the module name or a list of things you want to import. So if it's just a module name that it does, it translates to a default import in JavaScript. If it's actual list then it imports the specific things from that module and the second parameter is the path to the JavaScript module. So that gets that out the way and the next thing is each of the modules has a underscore underscore module underscore underscore constant and it's just the name of the module itself. The next thing is all of the functions, so private functions and the public functions and the last thing is it exports all of the public functions. And what the compiler does right now is basically focuses on kernel.special farms and the kernel module. Most of that is implemented. What's missing completely is m, caller, and super. What is incomplete is, so bit strings don't have pattern matching yet which I mentioned before. Import alias and require can only be used at the outer scope. So in Elixir you can use, you don't see it often, but you can use imports, aliases and requires within the lexical scope if you want to. Quotes right now ignore location and context options and the double colon, I need to revisit that for Elixir 1.1. Ali is used for, it'll figure out the types for bit strings, but there isn't any support for type specs yet. So that is the compiler itself. So the runtime is everything that you translated over, it's so that it can actually run within the JavaScript environment. This includes the pattern matching library and at some point it will probably include your protocol library as well as maybe processes, I don't know yet, that sounds hard. And most of the standard library will be defined here, most of it isn't yet, and some functions and macros can actually just be mapped directly to the equivalent JavaScript code. So the, why is that here? So the compiler can actually just map them over to their equivalent JavaScript code. So embracing the environment. So I was at a local meetup in New Orleans and a friend of mine, Eric Norman, who does purely functional.tv, he had a presentation on ClojureScript and one of the things I got from the presentation was that ClojureScript embraces the environment that it's in and that kind of, at that point made me sit back and think about what does that mean for this project. And what I found was Elixir, so Elixir runs on the beam VM and it is, it doesn't hide that away from you. So if you're using Elixir, you can use Erlang functions and modules without any special added things that you have to do, you can just call them without any issues. And so that's one of the goals of ElixirScript is to make it so that you're running in a JavaScript virtual machine in a JavaScript environment. The goal is not to hide that at all and to embrace it. And so if you want to use JavaScript functions and modules, then you can without any extra overhead or anything, especially that you have to do. So how do you use it? So there are three arrays currently and I probably need to put that down the two eventually. So there's an Escript which is built with each of the releases of ElixirScript. There's a mixed task if you add it as a dependency, you know, you also can use the ElixirScript module directly in your code. So the Escript, the arguments between here and the mixed tasks are exactly the same. It is just a matter of if you're using the globally defined thing or the one within your environment. You can see here they're pretty much exactly the same. The other option is to use the ElixirScript module within your code itself. And this is currently the only way that you can actually use macros. So if you pass in, so this takes a bunch of options, passing an environment option, what you can do is as long as the macros are acquired and available, then the ElixirScript compiler is able to expand those and use those. So now it's time for some demos. Yes. So they, I'm sorry, no, this is actual ElixirCode. So here I'm using an ElixirCode module in a function compile. And I'm just giving it a string of ElixirCode. And I just use the jQuery example for some reason. With the returns here, it will be a list. And the list, each item in the list basically corresponds to either, if it's just a simple statement like that, it'll just be one element in the list. If there's multiple modules within the code that you give it, each item will be a specific module that it was able to take out of the code. Does that answer your question? Cool. All right, so demos. So we just finished having a talk on Elm. So some of this might be kind of familiar. So this started out as a demo for using ElixirScript with React and Flux. And then at some point, I didn't exactly like it. And I went back and I started using Redux with this example. And that lasted, like, all of ten minutes because I was like, wait, I think I can go a little bit further. And so what I did was I took out Redux and I used an agent. So some of the functions in the agent are implemented here. Oh, I'm sorry. That, cool. All right. No problem. So what I did was I had an agent and I created a store module. And what this does is it wraps an agent and you have here, you have the state. So it's like the initial state. And what I have here is subscribers. So subscribers are anything that subscribes to state updates. And then the actual state of the application itself. And I completely copy the API of Redux here just to kind of prove a point. And you see down here, I mean, is that still good? So let's see. Oh, so here I have a dispatch function. And what this does is it takes an action. And this uses, this is using the agent update to, so what the agent update does is it takes the current state and it causes graphics private function, which it takes, like you would with Redux, you have the current state and then you have an action of what you want to do. And using that, it updates the state and returns it here so that the agent is updated. And then finally what it does is if there's subscribers, then it goes through and calls them to tell them to subscribe. So here comes the kind of dirty part basically where you're looking at right now a kind of bastardized JavaScript elixir thing going on, but this will get better over time. So here I have a React component and it's wrapping a canvas element. And the things I want to show here is you can see here I'm subscribing to the store so whenever there's an update, I'm actually painting the, I'm updating the canvas to paint and at some of these events you'll see that I'm dispatching, I'm dispatching actions that are, which you previously saw, I used to update the state. So using all that, you have something that is reminiscent of, something that is reminiscent of Redux. So if I run it, which one is it? Here we go. So every time I draw something, it's updating the state and this is all immutable state so I shouldn't say update, it's replacing the state, right? So each time, each dot, if you can see those dots, it updates the state and when I press a button here, it'll change to a different color and it's telling, it replaces the state telling it to use green. Here it's a different action, use a purple and you can make it large, whatever. So that's how you can, without using Redux, you can kind of get the same advantages of it within ElixirScript. The next example, thanks. So the next example, it started off as a friend of mine who we used to do a podcast together. On the podcast, when I started using, when I started doing ElixirScript and around the time when React Native came out, he was like, what if at some point you can use ElixirScript to write React Native applications and I was like, I can't think about that right now. But when React Native had to do is that it updated to allow for Android applications, I decided it was the perfect time to write an iOS application in the React Native. And so what I did was when you start, when you use a React, when you create a React Native application, what it does is it gives you some starter code, like basically a Hello World type of thing. So I took that and I rewrote it using ElixirScript and it's, once again, eventually this will get better. I actually can show an example where it looks a little bit better, but it's not something that you can use right now. So I'm just creating a React, a React component and it's doing the exact same thing that you would if you got the initial React Native application started. So I have Xcode running here and I'm going to start that. And then I'm going to do a Goat Watch and it's running over here. And just to prove that it's actually working, I will change this to ElixirConf 2015. I'll go back here, refresh it, and you can see that it changed. So it's just a small demo, but maybe one day it will be possible to actually write applications. React Native, NativeScript, I don't know, any kind of application that uses JavaScript within Elixir, in ElixirScript. Oh, the future of the project. So obviously implement more of the standard library, protocols, better macro support. So those are the two things I really want to focus on within the next couple of versions. Behaviors, source maps, because you don't want to, you don't want to, you don't want to debug that right now. Maybe processes. I've seen some work with, so they have ClosureScript as core.exe, and I saw a library called JSCSP that does similar things. And I know the models are kind of from the same root, but different. Well, they're a little bit different, so. But that might be at least something to look at towards making, using processes within this. And this better error handling as well. So that's it. Any questions? Thanks.