 My name is Hawi and this presentation is going to be a hands-on tutorial to walk you through what it's like getting started with ScalaJS. So the agenda for today, first I'll intro what ScalaJS is about. I'll go through the three main things that people tend to use ScalaJS to do and then we'll wrap up. So first, about ScalaJS, I'll go through the who, what, where, when, why. So who am I? My name is Hawi, I work at Dropbox during the day. I write lots of legacy, coffee script, Python and bash scripts. So if any of you want to come talk to me about what it's like refactoring an 80,000 line of legacy coffee script code base, you can come hang out after presentation. So I work on this ScalaJS stuff in my free time. We don't use much Scala at Dropbox, I think we have maybe 2,000 lines in some internal tools I wrote. And most of the work in ScalaJS is done by these two guys. So Sebastian and Tobias have done the bulk of the work. I have a few commits I managed to sneak in there a few months ago, but they are the ones who really made ScalaJS what it is today. So what is ScalaJS? ScalaJS is a Scala to JavaScript compiler. The idea is you can take a Scala source code, compile it into equivalent executable JavaScript and run it in the web browser. So in terms of performance, it's somewhat slower than raw JavaScript. It is significantly slower than Scala on the JVM. People often underestimate how fast JVM is. People say, oh, Node.js is evented and really fast, but actually it's not. The JVM is actually really pretty fast. But despite being slower than JVM and slower than raw JavaScript, ScalaJS is quite a lot faster in the Python that I write day to day, so it's not terrible. And executable as it produces, it produces my program.js file at the end, tend to range about 150 for a Hello World application to about 400 kilobytes for a large application using lots of libraries. So this is before GZIP, and then it's not small, but neither is it huge or massive. It's okay size, especially on the lower end. Most of the size is Scala's Bloated Collections Library. So, whoops. Okay, so here is what ScalaJS does to a small application. So this is a main method. It defines a variable. It has a wire loop that does some useless stuff and it prints it out. At the end, this should print out 1,000 to the console. ScalaJS takes this code and turns it into something that looks like this. So, your ScalaStyle method definition is now a JavaScript prototype assigned equals function. That's how you do methods in JavaScript at least canonically. Variables are variables, wire loops are wire loops. The implicit extension method string.toInt, which is actually materializes a bunch of wrappers that you call toInt on, have all been materialized in the source code. So it's not actually string.toInt. It's actually string.oxpredef.augment string.toInt. And you can see it all present in the JavaScript. Other things of note, similarly all the methods that you import are now fully qualified. So print line has become predef.printline. The method names are munged with the types that they take and return. So print line takes in the object and returns void. Main returns void doesn't take anything. So this is makeJavaStyle overloading work. Last thing to take note of here is that what was previously in Scala integer addition has now become JavaScript numeric addition modulo zero. So this is a little trick that we use in order to make sure that the JavaScript addition, which is actually double precision floating point addition behaves identically to Scala's 32-bit integer addition while still maintaining performance. So this is kind of big and bloated and really ugly. But what's important is that it's pretty straightforward and easy to understand and especially easy for computers to understand such that when you crunch this through the Google Closure Compiler, we get code that looks like this. So all the method names have been crunched really short. All the class names have been really short. It's way more concise and probably much harder to read. Thus, print line has been inline. This grey blob here is an inline internal of the print line function that the Google Closure Compiler decide to inline for us. Why? I don't know. The Google Closure Compiler is an open source tool that does a lot of magic to make your JavaScript small. And there are a lot of smart people working on it so you can trust that it will do the right thing. So this is kind of what the compilation pipeline looks like. I hope it gives you idea of what Scala.js tends to do with your source code. So, where can you find Scala.js? We have a website. So it's over here. It looks quite pretty. We have a GitHub page where the compiler lives. We have a Google group and we have a Fiddle. So, like JS Fiddle, this is an online interpreter which lets you run Scala.js code. So, for example, here's a small example which makes some sequences which you can't really bit hard to see but makes some sequences and prints out some results. So, yes, the compiler is running on a server. We have not managed to compile the compiler to JavaScript yet. So, we have a bunch of things to JavaScript including a standard library but not the compiler. So, that's work in progress. So, this is all running on the remote server. I have a compilation server running on EC2. Here's a more interesting example which actually shows you you can do JavaScript things like talking to a canvas in Scala. You can change these things. I'm going to make this white. I'm going to make this cyan. I'm going to make this pink. Why not? Why not? My compilation server seems to not be responding so it's not actually recompiling. So, oh well, let's skip that for now. Maybe you'll start responding later. So, okay. Back to the presentation. Let's pretend that worked. So, another way of looking at the question of where is where can you run Scala.js? And the answer is you can run Scala.js anywhere you can run JavaScript. So, this is not just websites. You can make websites with Scala.js such as this one. I'm not sure. Redirect, redirect. Okay. Well, never mind. You can make a website to Scala.js. You can also make node.js modules. You can also make Chrome extensions. You can do obscure things like someone made Autodesk Fusion plug-in. Oh, that's you? Okay, cool. So, these plug-ins are written in JavaScript. Scala.js compiles a JavaScript. Therefore, you can write them in Scala which is kind of cute. So, this is not just websites and more importantly, this is not just a JVM. So, you can run Scala.js. You can run Scala code anywhere at JavaScript code can run. If someone tomorrow comes up with a hipster microcontroller which only runs JavaScript because that's how you make things web scale, then you can definitely run your Scala code on a new microcontroller and have a web scale Scala application. So, if I loaded here's a play application set up with Scala.js if you want to try it out and I'm not sure if he has a link to the example here, he doesn't, but he downloaded and run SVT, it will work. So, Scala.js was announced last June, well, previous June, I got involved in September after watching Sebastian's video online his Scala Days presentation. We released version 0.1 which is a first stable version in December and right now we're working towards 1.0, so a lot of stuff has happened in that meantime but I'm going to gloss over that because that's all past and I'm going to show you what it's like now. So, the last question would be why Scala.js and the basic problem at least I think JavaScript is not a very good language. So, the a very smart person who invented JavaScript has decided that the good parts of JavaScript are about a quarter of an inch thick and the entire JavaScript spec is about two inches thick. So, that makes JavaScript about 1 eighth of the language good parts in terms of thickness. So, this was a while ago and if we fast forward to today the same person is saying that now even more parts of JavaScript have been declared un-good or even double plus un-good. So, even new is not working anymore let's not use that let's not use object create I know this object oriented language let's stop using this let's stop using now I gave you guys falsiness let's stop using it that was a bad idea. So, by this point well, by this point we see JavaScript about 10% good and by this point you say JavaScript may 4% or 5% good and the other 95% 96% is just out there to get you and crash your website in production. So, one solution for this is you want to try writing a language that works within the 4% or 5% of good JavaScript and enforces you don't step outside. So, Scala.js is not the first group to try this there's a whole bunch of them some like Google Web Toolkit our old style words that have been around for a while and kind of clunky but well known others like coffee script which is what I write at Dropbox is a very thin veneer that solves a lot of superficial problems very effectively solving these superficial problems or making the deeper leaving the deeper problems alone and not fixing them Others like Elm or Opa Lang are meant to change the way people do web development forever and so far haven't and to this next we add Scala.js So, Scala.js is our take on how to change web development forever we also so far haven't but there is hope So, the basic problem we are trying to solve is that JavaScript isn't good for a variety of reasons and Scala fixes a bunch of these reasons So, Scala is not 100% good we have Scala-XML we have Scala-Parsar-Combinators we have all a can build from rubbish in the standard library but nevertheless if you count the good parts of Scala I would say maybe 70-80% of Scala is good parts which is a lot more than the 4-5% of JavaScript that is good parts So, that's why you would like to use Scala.js in theory So, for the first demo we are going to talk about interactive web pages Interactive web pages are the main thing people use with JavaScript use JavaScript for you can't run anything but JavaScript on the web unless you use flash and flash is more or less dying right now So, let's talk about how to make interactive web pages using Scala.js So, I don't know if you guys can read this we are going to start from the template application github.com slash lihowie slash workbench dash example dash application so those of you who have laptops want to remember this for later you can take note if you google workbench example app you also get it So, before let's go to live coding now I have clone this earlier this is a small Scala.js application let me kick it off in the browser So, I'm going to say every time I change the code which is what Tilda does run the fast optimization which is relatively quick but does not crunch it down all the way and also does not take forever so we can run it interactively and constantly iterate on the website if you look at the code I am defining a case class I am defining an object with a main method bunch of code in here I am defining some variables some helpers every time I call the run method it does 10 iterations of some algorithm that sets a color of the renderer and draws a one by one rectangle one by one rectangle so x is p dot x y is p dot y w and h are both one on the canvas so this you don't know what this does so I will show you so if you go now to local host index dev this draws a suprinski triangle so this is a kind of neat thing you can probably ignore these things because these are just a source map not being found so I've set this up such that the log spam goes to the browser so if I change it you can see SPT recompiling here just say let me keep flipping back to the console and the browser updates on its own so no hands so come on save okay why is it not saving okay anyway so for now the only thing unusual about this application is that we have these js export things which are the way you tell ScalaJS hey these applications these methods and objects are going to be available from javascript so like java unlike javascript ScalaJS applications need to have an entry point they don't just run top to bottom and evaluating every statement along the way so this is how you do that um this takes a canvas a dom.html canvas element which is a javascript type that is defined in javascript so it's this fellow um it is a it is not a Scala type it's not defined by us we just have a facade to it to let you use it and other thing that interesting sometimes we need to cast things before we can call methods on them because in javascript you get back a thing of uncertain type and you just call whatever you want and it won't let you do that so in this case since i i know i am passing in 2D as a string i am getting back a canvas rendering context 2D which is again a javascript type as a result so let's see if i can make the reloading work so gray yes and it should reload it starts off kind of slow because the Scala compiler is very slow and the ScalaJS compiler makes it even slower but with incremental compilation and with a warmed up JVM it will become fast in a minute so other than this code which is what's drawing the Serpent C triangle let's look at the project layout this looks like a normal SVT project i have a gitignore i have a build a SVT first thing i'll look at is i have this index dev.html page which is what i'm going to in the browser index dev.html up here and ScalaJS applications in this case runs in a web page so i'm providing a html web page for it to run it is a very boring web page for the body it has one canvas which i hard coded the width and height here i am including the ScalaJS output blind executable for now it's called example fastoptimized.js this is the little daemon that's loading all the logs damn to the browser and this is what kicks off the ScalaJS application i am calling ScalaJS example.main and i am passing in the canvas which i'm getting as document.getElement so this is what's calling this object this method so that's how the html page works if you look at the sbtconfig let's look at the plugins i'm using i'm using the ScalaJS plugin version 0.5.5 that's the latest and i'm using this workbench thing which is what forwards the log spam to the browser lastly let's look at the main build file so settings from the plugins we have sbt boilerplate we have one library called ScalaJS DOM which is what provides us the nice sorry what provides us a nice statically typed DOM API so we can call for example DOM.alert in a statically typed manner so if you run that run that boom hello let's get rid of that because it's kind of annoying and we have some boilerplate to tell the workbench plugin how to reload the page and reload automatically so that said and done let's look at the output file so if you look at network tab go away if i didn't you recompile okay now he's recompiled if you look at the network tab you'll see the example faststop.js is now 844KB which you can see here as well in my target folder so it takes a while for IntelliJ to open a megabyte of JavaScript and we pull it out and we look for the code most of this is a standard library which I said is kind of fat but this code on the right corresponds to roughly this code on the left so as I told you earlier it's kind of bloated all the methods have their names mangled with type signatures but nevertheless it's relatively straight forward it's not easy to follow but you can kind of see what's happening so count is zero I don't know what this terminal is I don't know what this step is I think this is the inline I think that's the inline part of the four of the four comprehension Scala.js inlines four loops on ranges so that's kind of nice so you can see now my inline four loop has now become a wire loop because Scala.js has optimised it such that and here you are seeing I'm calling fill style and fillRect equals this huge monstrosity which is what happens when you do string interpolation in Scala so that's more or less what it looks like after fast optimisation let's take a moment and look what it looks like after full optimisation I'm going to change it to full optimise and this will take a moment takes a moment longer than fast optimisation because the Google Closure Compiler does a lot more optimisations they're not better or worse it's just more so direct optimising to example.opt.js so now if I change the page to instead load example.opt.js come on give me back the console let's see so and we refresh the page we'll see that now we have example.opt.js which is 140 kilobytes so this is what I told you that it's much smaller after you crunch it down it's not tiny so closure script comes down to about 60 kilobytes and pure script which is a Haskell dialect goes down to about 20 kilobytes the standard library is kind of bloated so even after dead code elimination and optimisation we still get about 140 kilobytes so if you look at the code for the fully optimised version it looks like that so we probably don't want to read this ScarJS example app so here's a class name I can't read any of the rest but you just have to have faith in that the people at Google working on a closure compiler would not break your code if you follow their rules and you're following their rules so a bunch of smart people that hopefully will not break your code at the same time making it run faster as you can see it behaves identically in the browser so let's take a moment and let's look at how we would publish such an application so I'm going to open up Finder because that's what you do and at least to a first approximation I go here I take this whole thing I copy and paste it to my dropbox public folder replace just stomp over the old thing and now I can go to the public folder go to the HTML page open it and here you go so as a first approximation Scala.js projects are just javascript files there's nothing special about them if I copy a public link I believe it should work on the internet unfortunately my dropbox client seems to be borked so let's go to dropbox.com and let's copy the public link there so public folder Scala.311 index there copy public link yes I want to copy it there you go on the internet if any of you want to copy 7997532 slash classes index dev Scala.2.11 you'll see this it's now on the internet so this is more or less what you can do with a Scala.js application it's kind of cute it's not easy to share your interactive visualisation through your friends like if I tell my friend here here's a jar file please run it it will be like what's a jar file why is it asking me to upgrade my Java and ask to bar when it upgrades on the other hand with Scala.js I can send them a link to my Dropbox public folder and I have a website with a pretty visualisation I can mail them the HTML and JavaScript which comes up to about 200 kilobytes it's perfectly reasonable so enough talking let's go back to the original thing let's turn it back to dev mode so working will be faster and let's turn this into an interactive website some of you guys may have seen my previous presentations where I turned into a game I've already made a game so I will not make a game again so let's make a website so first thing to do is I'm going to look at my HTML page websites don't use canvases at least not much I'm going to get rid of it instead I'm going to use a div which I need to pass in my div so I need to pass this in here to pass in the div and I need to pass it in here just so I'm just telling my SPT plug-in that now when you reload please use this snippet of code to reload the page if you don't use the SPT plug-in it's also fine you just need to press command R manually so it's not a huge loss so I'm now passing in a div and if you look at my console nothing's happening so first let's since I'm passing a div I want to change this so a HTML div element you can see I can auto complete the div element and once I tell IntelliJ hey it's a HTML div element IntelliJ says hey all this stuff you're doing down here is all totally wrong because you can't get the rendering context on the HTML div element and you can't do stuff to a rendering context which you couldn't have gotten so that's okay for now since I'm changing this I'm going to get rid of all the stuff IntelliJ complains about that's the best way to make your code type check and I'm going to say hello world and as I said the first time is slow because compiler is slow it will speed up in a moment and now we print line hello world to the browser console down here so print lines go to the console I can say what can I what should I do next I'm going to rename this from canvas to container because it's not actually canvas anymore I'm going to say inner HTML equals h1 hello world I can't type because it's cold outside it's like zero degrees the road was covered in ice this morning so now when I change this I have hell okay so that's the basic of first approximation of how you work with ScalaJS all JavaScript APIs are available you can use DOM.alert you can use DOM.console.log which behaves similarly to print line as you can see because of the library I include the earlier ScalaJS DOM basically everything in the DOM has been typed we have gone through and copied all the types from Mozilla's documentation and they're now all available in the editor which is very nice so however I don't want to make a website by using string concatenation because that is fragile that's verbose and that is makes your site open to cross-site scripting vulnerabilities so instead I'm going to use a library which I made called ScalaTags so I don't know if any of you have used it ScalaTags is a small HTML generation library that runs on both JVM and ScalaJS so it's a cross-platform Scala library one of a number of them so I'm just going to copy and paste this in I need to restart SVT because I changed the config IntelliJ is going to have to reload IntelliJ and SVT like fighting over my IV cache that's unfortunate container so instead of setting that to hello world I'm going to just clear it and I'm going to say container.appenchild so this is a normal JavaScript appenchild method and I'm going to render a fragment using ScalaTags so I can say ScalaTags.javascript.dom version.iwanteverything here I'm now going to say I want to render a div whose contents is a H1 not he H1 hello world and a paragraph saying I am Carl so ID and SVT and not just SVT but also my browser is complaining at me because it's expecting a node and giving back a typed tag so this is just an unrendered fragment and I need to call render on it for it to be happy so la la la and it finishes compiling I have hello world I am Carl there we go so it's slightly ugly right now let's grab some bootstrap because that's how I make websites slightly less ugly than they already are download I don't download it cdn here we go bootstrap from the cdn this is again a normal html application nothing special here I think let's make it xhtml and then now when I refresh the page it should be bootstrapy and hit so now it's bootstrapy let's try making it take some input so one thing the html interactive web pages do is that they are interactive so I'm going to put in an input element so all these elements are nicely type checked and given by the Scala Tags Library so I have an input I can type stuff in nothing happens because the input doesn't do anything yet so to make the input do something I would need to render the input to a variable put the variable in here put the rendered input in the fragment and now I have an element of type html input element so this is exactly what you can do in JavaScript except it's much less verbose you don't need to call document.createElement by tag and put the tag name it's also much more type safe so now it knows I have a html input element I can easily do things like get the value of the html input element and set the on key up for example equals event handler which looks like that with Scala 2.12 this will disappear because it will be inferred as a single assignment method interface for now we have to use it still and let's just print this out so refresh you can see it's printing out the stuff I type in here let's do something more interesting let's have an output element and put the stuff in the output element so it's quite cute you can see if I try to say output.value it complains because it knows that output is a div and it knows that input is a html input so type safety is great I'm going to put this output element below the input element I'm going to say output.textContent is equal to the value of my input okay this needs to be here for the compiler to be happy and so here's a small interactive webpage that does not much but kind of shows you how working with Scala JS works so next let's make it more interesting let's turn it into auto complete widget because at Dropbox we are spending several weeks writing a new auto complete widget because it's very difficult in coffee script so let's say I have a bunch of things auto complete apple banana mango mangosteen Mandarin let's give it some similar things for it to be interesting so now instead of just rendering the input I want to render a list of things so let's say I'm going to clear the insides and I think it's in the HTML to clear it and output.appendChild so again this is a normal JavaScript API an unordered list which contain I need render it and I need for fruit in fruits yield a list item with the fruit in it so this will just render everything every time so and everything every time not interesting so I can change this and make it if fruit.startsWith myInput.value so to upper let's make it uppercase sorry it's kind of running off to left side the screen but you guys will have to see it so if it matches I will render it apple nope that didn't do it to lowercase to lowercase there we go so now when you see it's happening I can type apple mango steam so Mandarin so kind of cute let's say I want to highlight it I can take the fruit what do I want to do now I want to take the fruit and split it into first and last parts of the fruit fruit.split I think there's a split at method myInput.value.length so let's put this at next line so you guys can see so I'm going to make a HTML span first with background, color yellow so this is all my Scarletechs templating library at work and I'm just going to put the last as four method text so now I have an autocomplete widget which highlights stuff so this is quite cute considering how little effort I put into this it has been about 20 minutes since I started coding and I have an autocomplete widget that runs locally so what else do you do with HTML pages one thing you do with HTML pages is you don't just run them locally they tend to make requests to some web server on the internet somewhere so I'm going to show you that now so the API we're going to use is called open weather map so open weather map tells you the weather for example it tells you that in Tuhai in China it is 32C which is kind of hot what's interesting is that they have an API which lets you get this stuff for free so for example I can show that I think there's a search functionality which kind of matches what we want to do with searching for fruits so here's the weather in London as XML if I don't XML except JSON I can turn London into LON and they will search when the city starting from LON there are many more so let's just copy this query into my web page and let's say query equals that let's split it into multiple lines so it's not so ugly fail and so where you make AJAX call and javascript the same way you make AJAX call sorry the way you make AJAX call and ScalaJS it's the same way you make AJAX call and javascript fail XHR equals new with DOM.x ML HTTP request XHR.open get XHR.onload equals same I need to do this kind of annoying event handler I will go with next version of Scala why is it complaining because I need to pass I need to pass in the URL parameter so when you pass in query print line XHR.response.text go so let's go back to our example application it should be making AJAX call oops I did it wrong in javascript you need to say XHR.send and when that finishes loading you can see the compiler is now warmed up now it's good now it's pretty quick and now I have the blob in the browser so let's format it in javascript you can format things by parsing and unparsing them so at least you can format JSON by parsing and parsing it so let's parse it and js.json.stringify and I need to pass in some sort of space param so these are the statically typed façades we're using for the javascript APIs if you want you can use them dynamically but if you spend the time to specify what the types and objects are called and what the methods are called you can use them with autocomplete and in editor highlighting and all the other nice things for example with ScholarJS you have named parameters which you still don't have in javascript what's wrong blah blah blah there we go so now you can see this is the result of the Ajax call you made to the server let me scroll up to show you the top of it so it is a JSON object with some values here it has a list value kind of small but it has a list field which contains a list of the data from each city like the ID, the name, coordinates, lat, long all that stuff so let's try to get some useful information out of this so instead of just stringifying it let's get rid of all this thing I'm going to store the parse JSON as data and I'm going to say data.list.map so each item for now is js.dynamic so the data variable is a bit hard to see here but it's dynamic which means that it will not get type check whatever you want, if you screw it up at runtime it will blow up but it also makes it convenient for dealing with things like JSON from a web server which you haven't bothered writing so I want a tuple of item. let's say its name I think it's item.main.temp which is this fellow down here and let's get item.sys.country so I know I need to get a country that goes in every Spanish-speaking country in the world and so now it's a dynamic object which means we can't really do much with it yet but if we cast it into a typed object for example I'm casting it to a tuple of string double and string we can then use it and let's convert it to a normal sequence we can then do things with it so val items equals that items. now it's normal sequence I can call for each and just print stuff out so this is casting like any other casting it's all up to you, if you screw it up it will blow up at runtime but after you finish casting it and you're back in the typed land again and if we screw up for example for each here the compiler will complain so let's go back down to the output here is a list of tuples of the data we extracted so let's make good use of this let's take this query and let's chuck it into the on key up the on key up handler so here I'm going to make the query instead of appending immediately on the on key up I'm going to append after the results have come back from the server and instead of using fruits I'm going to use items so I guess I can get rid of these fruits for now and so now it's complaining I can't call to lowercase on a tuple let's break it up into name temperature and country so if name dot to lowercase starts with that this is name so after the name we are going to put in let's say comma country dash temperature I don't want the string, I want the variable so this is constructing HTML fragment and now when I type stuff in I get a lot of I get a lot of London's which probably means I need to make the query smarter instead of hard coding learn I'm going to hard code soft code input dot value and I think I need to move the clearing into the onload to make sure I don't get duplicates like I have here so now when I type stuff in I can say what's the weather in London like it's in Kelvin's which is not very helpful so Kelvin's to Celsius let's let's convert it to Celsius for you guys who like Fahrenheit you can convert it to Fahrenheit too so now let's do London let's make it integer because the floating point rounding errors make it super ugly sorry so London there we go London, California is 1 degrees London, Great Britain is 9 degrees Portland, Oregon is the lowest weather station is 2 degrees it looks like Singapore where I'm from is pretty warm at 26 there are a bunch of San Francisco but the one in the United States is 18 degrees C so it's been 27 minutes and I have a little working autocomplete for you that uses a remote server so this is kind of how you get started using ScalaGS, you download the example app I don't see any of you downloading it but whatever you can try later and you start hacking around with it to make your application work you can do anything you can do in JavaScript you get types which is very nice you can not use types so over here for example I'm using dynamic and if I screw up for example a call to map I call it map instead of map it should blow up at runtime there you go, can't call map of undefined so if you're going to fall back to dynamic it's up to you if you screw up it'll blow up but it's convenient in many cases in the vast majority of the program you can import autocomplete, jump to definition all the other nice things that you expect from modern programming environment so let's go back to slides and moments what are takeaways from this part well one is that ScalaGS works you can make something, you can debug it you get all the nice compilation errors in the browser you can see misbehaving and fix it you can publish it so this application is now what I showed you earlier was 140 kilobytes published let's fully optimise full of JS HTML generation using ScalaTags is quite nice and it's much safer and much more concise and most other templating languages and also much more convenient to use there's no files lying around with special template format you just generate stuff in your source code and splat it wherever you want and lastly working with a DOM is much easier with types I did not use my full opt was wrong so I didn't use jQuery or any fancy library to work with a DOM I just use DOM methods and the thing is DOM methods even though they are confusing it doesn't matter how hard to remember if you have a complete list of everything you can do dropping down in the editor in front of you there's no special abstractions totally bog standard DOM APIs but with types, using it directly it's reasonable so my asynchronous thing has finished let's look at how big the output fully optimised binary is for this application it is 143 kilobytes so again it's not huge it's reasonable, it's not tiny it's mostly the standard library and it's about the same size as you would be happy to deploy the way it's set up now you cannot use a CDN for the standard library so the reason you can't do it what we are doing in Scala.js is we are doing a full program optimisation so before we did whole program optimisation the standard library would take up 20 megabytes of JavaScript so Chrome would slow to crawl trying to load in this massive blob and that's how big it is if you load the whole thing what Sebastian has done is he has set it up such that any unreachable code will be eliminated similar to what ProGuard does but so this makes it down to about 800 kilobytes a megabyte and when fully gets crunched down it gets crunched down to about 100 to 300 kilobytes but it means that each of these whole program optimised blobs cannot share code with other whole program optimised blobs so if you have two Scala.js applications both of them optimised they're going to have two several hundred kilobytes sitting on your web page maybe it's okay so maybe 100 kilobytes isn't such a big deal after all so the email said that I was meant to give a break after the first 40 minutes is that still a thing so I guess I can take questions for now since you guys yeah you can so I don't remember the bootstrap syntax for doing things now but let's say I want to let's say I take my span my list item and say class well I can say class here equals my class but I've given a shorthand because class is a special name they use a lot so I just make it class I prefer to class with a K because class with a K is kind of annoying and now if you reload the page and I fill stuff in I believe the class should turn up sorry nope, the class didn't turn up I don't know what I did wrong but yes, you should be able to use classes so the answer is yes and you have two options one is you do it dynamically so similarly to what I did with my JSON blob you can just say js.global. whatever you want and it won't type check it and it will compile straight to JavaScript and it hopefully will work so if you have a JSON and DOM.xml.htp request we went and wrote out a spec for what the library API is and you work against that interface so the DOM library is not a special library there are several other libraries if you go to Scala.js.org you will see that we have the DOM, we have Scala.js React by David Barry and these are library like JavaScript libraries we have Scala.js Angular by Xavier so it's not a huge selection and if you always want to you can fall back to doing things dynamically just by using js.dynamic but my experience has been that it's always better to write static types because then you get confused once at the interface rather than getting confused everywhere within your program so I've used Scala.js React a bit, I've not used Scala.js Angular but this guy is basing his startup on it so I guess it works I don't know how much better we can make the optimiser the root cause of this bloat is that the standard library contains a huge amount of stuff and all the stuff is heavily entangled together so we already do some pretty amazing things like in Scala.js you get inline for loops for free and even given all that optimisation it still is about this size so I'm not sure whether we'll be able to make it as small as pure script at like 20MB blob simply because of Scala Collections any collection you use, any option any sequence, any for loop tends to pull in all the other collections and include them in your executable so I don't think anyone's working on doing that right now no one on the Scala team is as far as I know so question what's left for 1.0 let's take a look what's left for 1.0 Scala.js issues milestones so next is 0.6 which is basically a pre-release 1.0 a lot of edge cases so things like this would improve performance things like this aren't really implemented properly right now things like this would improve performance this is for future compatibility there's JVM default methods and Scala.js will take advantage it's a lot of polish so most of the hardcore work has already been done let's look at, so that was what 0.6 1.0, nothing planned yet but basically most things are already there there's a whole bunch of polish things for example object.hashcode by default returns 42 because we didn't need it up to now and now we fixed it there's a bunch of other small things around edge cases Java.io.printwriter it was not implemented so now they're going and implementing Java.io.printwriter and making it work which is surprisingly difficult just to make sure we cover a broad base of things you can use so I have a few and there are more which I can't show you because there are some persons company using it, that's not me so let's look at some examples this fellow is about the 2000 lines of Scala 1.5k lines of XML online video game where you can draw things around and roll around, the goal of this game is to kind of get to the right side of the screen so let's see if I can do that but so this kind of shows this kind of stuff Scala.js can do it's not just for making small hello world this is actually quite a large amount of code it interrupts with a third party javascript physics engine which kind of answers your question how well can you interrupt with physics so this game uses chipmonk.js which is a javascript physics library here not written by me if you go to the source code of the game slash you'll see that it's not a huge amount of Scala files but it's a good amount of Scala files for example, here are the static types I use to interrupt with chipmonk in a type safe manner I could easily use a non-type safe manner but this works as for bigger than that I don't have any I can show you one guy is writing his trading platform one guy is writing a startup in Korea there are a few people like Scala around the world using it for real work I write coffee script for money so I don't actually use it for real work let's do that now thread.td what happens if I try thread.sleep I can't do that in javascript it will give me a warning at build time thread.sleep is not defined and it should blow up at runtime you need the source code to translate to javascript so that's the limitation any library needs to be pre-translated to javascript first usually in the process of pre-translating you'll find all the bits and pieces more in the moment let's go back to the slides for now because this is exactly what you are asking so the next bit is about making cross-platform libraries how convenient yes I haven't set them up for this demo if it throws an exception in the browser it will give you the Scala files and the Scala line numbers still not perfect but work in progress so cross-platform libraries so one reason you make a cross-platform library is because you can so Scala tags started out as a JVM library because ScalaJS did not exist in 2012 it munger strings and spits up the strings as a blob of HTML there's no reason that this must be JVM specific and it's not so if you look at this nice picture everyone up here is using Scala tags on ScalaJS everyone down here is using Scala tags on ScalaJVM so it's not a huge project but it's not just me who's using it there are other people out there who are also using it and if you can cross-compile it why not allow your code to be used by more people which is always nice apart from Scala tags if you have a good number of libraries cross-compiled this is a small selection if you go to the website ScalaJS.org you will see more so Scala tags we have chain propagation the left side is someone's eye-made the right side is existing libraries our community has taken and cross-compiled without asking permission so we have ScalaZ on ScalaJS we have shapeless on ScalaJS monocled, parboiled too all work on ScalaJS again we had to cross-compile them using the source code we can't just take in the existing jar and using a ScalaJS project but we have people maintaining forks which basically add to these projects so if your Scala project really truly does not use any JVM specific dependencies then this is what it takes to cross-compile it to ScalaJS this is what David Barry used to cross-compile ScalaZ mind you ScalaZ is a huge library the jara file for ScalaZ is 50% larger than the jara file for the standard library so it's this huge thing but it does not use so we just cross-compile it for free almost so this also is interesting because it puts the rest of common thought that oh, there's no point cross-compiling to javascript because you're going to have to know javascript anyway but this is clearly false because Tony Morris and Lars Hooper who wrote and maintained ScalaZ did not know about ScalaJS and we're not thinking about cross-compiling for javascript similarly Miles Sabin who's the guy who wrote shapeless also was not thinking about ScalaJS added a bit of config and cross-compiled it and now people can run ScalaZ in the browser just because you can some of you may be wondering so I said if you don't use any JVM specific functionality so here's a short list of can users and can't users in ScalaJS in short reflection, operating system threads Java like Java Java not Scala but Java source code networking Java tools can't use so this rules out things like spray, ScalaTest Acca, ScalaPickling all these use these not supported APIs most of java.lang which is very basic has been ported almost all of Scala except for things like the parallel collections Macro is working ScalaJS ScalaAsync Upical is realisation library heavily uses macros as a replacement for reflection which is often a trend if you give up using reflection you often can use macros to accomplish the same functionality you can use all the DOM APIs like how I showed you using XML HTTP request and all that stuff so here's a short list actually cross-compiling things is an ongoing effort yes it manifests itself in an error in the compilation and it does not compile okay, so if it is as long as the things which were not usable in the browser do not get called transitively by any entry point of your ScalaJS program it will be okay so for example the Scala standard library has a number of things that do not work and I did not call parallel collections and so it's happy if I did call it it would blow up it would give an error saying no doesn't work yeah what web workers yeah web workers it could work I think there's one guy who is exploring on ScalaJS using web workers I have my doubts whether that will work but it's entirely possible so now for some live coding so I'm going to use the project github.com eHowE slash utestexample-module and this is going to be an example application which cross-compiles to ScalaJS and ScalaJVM so let's open that up now I've downloaded it earlier this window let's kill this and let's go back to utestexample-app let's run it on a unit testing loop so if we open up this library we'll see it has a JVM subproject each of these subprojects has a source folder subprojects has a shared folder the shared folder in JVM is simply sim linked to the shared folder in ScalaJS so the shared folders are always guaranteed to be the same contents if you look at the build files just because that's interesting instead of the workbench plugin which was designed for interactive web applications we have the utest JavaScript plugin which is meant for unit testing libraries on both platforms and the same old ScalaJS plugin here you can see that this is basically what the utest.js plugin gives us convenience in text for defining a library with some shared settings over here some JS specific settings here and some JVM specific settings here so now that setup you see that I've run unit tests and it runs twice it runs once on ScalaJS and once on ScalaJVM so this library is more proof of concept a small number of things so functionality number one it lets you square numbers just in case you didn't know how to you can include this module it lets you square numbers functionality number two it lets you eval JavaScript strings functionality number three it lets you ask who am I running on on ScalaJS it say ScalaJS on ScalaJVM it will say ScalaJVM so here so what's interesting about this library one is that lots of functionality which lives in a shared folder is written once and if I change it here it's guaranteed to stay in sync it will not diverge because it's simlinked two is that functionality that differs between platforms can be written separately for example this is implementation of eval.js in JavaScript JavaScript has an eval method because that's what you do in JavaScript eval strings again it uses rhino some of you may have spotted it in the earlier build file and rhino requires a bit more boilerplate to eval the JavaScript string but in the end it evals it and things so eval should behave identically in both context and if you wish to you can include code which behaves differently depending on what platform it's running on for example who am I returns different things so that's the library code let's look at the unit test code I can have shared libraries code I can also have shared unit test so here's a shared unit test that tests our square method because you never know when you screw up the implementation of multiplying two numbers and you can see it does some asserts it works if you go over here you can see it's happy over here is implementation of our eval.js method now this is interesting because this lives in the shared folder it's testing implemented separately on each platform so just because your code is implemented differently doesn't mean you can't test it once and this is what Scala.js let's you do of course it's up to you to make sure that two implementations match so if I go to for example Scala on the JVM and I screw this up somehow now you'll see recompile and you'll see one of the test cases pass and the other fail so Scala on the JVM blew up so it's up to you to make sure it matches but if it matches, that's great you don't need to worry about it the unit test can be shared lastly, apart from shared unit test you can also have separate unit test for each individual platform for example, I have one unit test to make sure who and my returns Scala JVM and I have another unit test which makes sure who and my returns Scala.js and Scala.js so if it behaves differently it's fine so you test is convenient in that it lets you it lets you have each test have a returned method which is just stringified just so you can see in test results as a sanity check visually to make sure it's doing what you expect so I'm going to make it return who and my on each of these tests and when it finishes running you can see the first set of tests which you'd expect lastly, you can do things like if I go to my shared code and I try to do something bad like that because I can't sleep on Scala.js but it should work on Scala.js it blows up on Scala.js and it works on Scala.js so this is more or less how working with cross-platform libraries feels like in Scala.js to go back to the slides these cross-platform libraries it doesn't of them right now not a lot but a good number code that works on both platforms can be shared even unit tests code that's specific to each platform can be provided separately again even unit tests shared code can test non-shared functionality and overall it actually kind of makes sense whatever you want to be shared you chuck it in a shared folder whatever you want to provide separately you chuck it in the relevant source folders in JS and JVM so it's a good SPT publish local so by default SPT will run it on both sub-projects that's what SPT does and if I look at .home.id2 .local I think it's on the com.ly com.ly howee you'll see that there is a demo module version Scala 2.10 and a demo module version Scala JS 0.5 version Scala 2.10 so cross publishing libraries works so that's it for libraries so the last thing I'm going to talk about today is client server integration so this has long been the so-called holy grail of web development where if only I did need to write all my algorithms twice in two different languages with complete different semantics and I march constantly serializing and deserializing data back and forth web development with the theory would be much easier so for the example I'm going to use today is going to be spray template so this is not code that I wrote this is code that Johans Rudolph and Matthias wrote these are the spray guys I have no hand in this so if I go, I've checked this out earlier and let's go to my spray template and let's open it up in IntelliJ spray template here we go this window so these guys have set it up such that I can easily start a spray server and you'll see it take effect um this is a pretty straightforward template so let's look at the build files first it includes this SPT revolver project plugin which is all it does is let you auto reload the server when code changes it contains a bunch of dependencies which are basically Aka and spray so not surprising for a spray template it contains unit tests as you know for now and it contains configuration and some source code so it contains an app which sets up stuff and it contains a small server which runs with a route which lives here so if I go to the browser so I believe this connected to 8080 so if I go to the browser host 8080 say hello to spray routing and spray can if I'm not mistaken come on it doesn't reload the browser but I can reload it myself so this is a spray application let's make it work with ScalaJS so I already made a small ScalaJS project earlier so let's open that up again workbench example app I'm going to open this in a new window this time so we can look at both of them at the same time so over here we have ScalaJS and over here we have spray how do we integrate ScalaJS and spray so the most straightforward way is to create a sub project in your spray app program so let's call it client I think SVT needs you to do like val client equals project.in file client otherwise it won't be happy and then integrating the two is basically a matter of taking the source code from this fellow and chucking it over here and yes I don't know what I'm doing but I'm pressing okay taking the build SVT file also chucking it in there and yes add it to git, thank you and I guess taking a project the plugins and merging them so okay so now now I have a spray ScalaJS project kind of so if I run slash fast op js in this spray project it should then compile our ScalaJS application so let's take a look at that so waiting for log, waiting for log is fighting with my editor editor's done and in a few moments you should see it turn up under this folder okay so it didn't, why didn't it turn up? oh because it was used to compile, let's get rid of that where did I put it where's my thread here it is, kill it okay try again compile compile compile so again Scala compiler is kind of slow in practice for interactive development when the JVM is hot the compiler is a lot faster and it's incremental so it's a lot faster so now if I look I have example fastop.js which is the same file that we saw earlier so the question is for example fastop.js from my client project and chuck it into my server project so one thing that SVT let's you do is that it lets you wire things up differently depending on how you configure it so for example my IntelliJ seems to have frozen not sure what it's doing give it a moment so the idea is you take the output of the fastop build step and put it in the resource directory so you do this by saying resources resources in compile plus equals fastop.js in client compile so this is a weird magic incantation like most of SVT so if you think it's confusing that's okay because I also think it's very confusing but this is how you wire up things with SVT and then it's going to complain because I need to import and you import the fastop.js task so skala.js.sbtplugin. no skala.js.sbtplugin.keys.all so now if I run SVT re flash start we should see that it will turn up in the resource folder of the spray project and should update automatically because of this dependency that gets added here so this is all available online don't worry about memorizing it all three examples are on the internet on github so now if I look at my spray folder you see I now have my example fastop.js I haven't bothered copying over the source map whatever if you want to you can and error messages will be better so if I go to my spray server and I go to fast example fastop.js it doesn't work and if you look at why it doesn't work this server so simple it doesn't even serve static resources which maybe is what you want so let's make it serve static resources let's say let's say that this html page is only served with server for a single slash I think it's like path single slash this is all spray stuff nothing skala.js specific and let's say that anything else goes to I think it's a get from resource directory so this will make it serve from the resources so after that recompile recompile what's it complaining about am I missing a curly brace somewhere I guess I'm what's wrong maybe I'm missing a curly brace too many curly braces yeah too many curly braces okay so let's try that again so now if I serve this up it works so now my skala.js application is being served from the spray server the application currently is not and to fix that I'm just going to take the html from here and chuck it here because that's how you do it that's one way of doing it simply and fastop.js that's right save refresh the page and now we have our skala.js application being served from our spray can server so that was easy so if you look at what actually matters in this code base the number of lines of code need to do this inter project integration is four lines here um one line here the skala.js plugin and not this file one line here and I guess this is a line that's important making it serve the fastop.js file so that's kind of what a minimal skala.js spray integration looks like and you can do more things I'm not going to do it now you can do similar thing with play whatever you want all you need to do is take the output.js file whether fastopt or fully optimised and chuck it somewhere that your web server can serve so this was a minimal skala.js project integration looks like let's look at what I would consider a more optimal skala.js project integration looks like so I'm going to use an existing branch because um get reset hard head get checkout auto wire let's get clean too I'm going to use existing branch because it's a reasonable amount of setup to get what I would consider a good um integration but I believe it's worth it so let's close that server look at what is now our example and run the same thing re start so that will start up our server so this looks similar to the project earlier we have a client folder skala.js example instead of having the root project put in a server project no big deal no real difference um configuration I have a bunch of shared settings I have a bunch of client specific settings I have a bunch of server specific settings interesting shared settings include shared libraries which work on both skala.js and skala.jvm I include them once they work on both platforms that's kind of neat so if I go to local with 8080 now I will have a file browser or something like a file browser so I say target so it's making Ajax call to the server to find out what's on the file system because the browser can't access the file system and if you look at what's happening in the network tab for example the last call ask for the path at target skala and got back a response which is a nicely formatted JSON string with all these things inside so we have not looked at the source code for this application yet so let's do that now we have a shared folder like we saw earlier client and server each have their own non-shared sources client is skala.js application similar to what we saw just now it has a bit of boilerplate up here for doing RPCs I'll explain that later let's move this one side come on tell EJ, move it there we go on the server we have a very similar spray can server as we had just now there's some boilerplate here for doing RPCs again here I've decided to make the network page get generated by skala tags rather than by XML literals because I can, skala tags runs on both platforms so what's interesting is that this list this list Ajax call which sends back and forth nicely formatted JSON is this list method here and on the client let me make this smaller and then we can see the console output on the client list call here so where's the serialization code generated by a macro where's the routing code generated by a macro what's the advantage of this if I screw it up the compiler will yell at me everything will be terrible if I actually do want to change it for example I can change it to list because that's what my boss will me change it to the compiler will yell at me because API trade does not have a list HAHA method so I need to change it here to list HAHA and then the compiler will yell at me because this list method or rather this server object which extends the API trade does not have a list HAHA method so I'm going to fix that too and when all is said and done and it finishes compiling it will only compile when the compiler is happy and now any Ajax calls are to the list HAHA method it's not less fragile than what I do at work working with Python and CoffeeScript where everything is a complete mess and you change things, stuff breaks you change things, stuff doesn't break you push it, stuff breaks you roll back the push with Scala.js and Scala.javm integrated like this you have static checks not just in the compiler but also in the editor where if I mistype something it will not go through the compiler will refuse it let's say I want to change how it works let's say I want to return instead of returning a string I'm going to return a case class of strings so let's say case class file, data name is a string size is a long string and long so I'm going to return files if .getName .startsWith yield f.getName f.length so this will return a tuple so it's complaining it doesn't match up so why is it complaining the API trade expects a sequence of strings which is this trade it needs to be a sequence of file datas oh, this guy needs to be file data too so I can probably just get rid of this fellow because it's inferred automatically and then on the client you see it let me figure out what's going on type so I think the problem is I need to move the file data because it's used in the shared folder API trade to the shared folder makes sense I guess so what's the last thing it's complaining about on the client well for one my name is still wrong I converted it back to list so let's convert it back to list what else now it says getting a file data which it doesn't know how to put in the DOM so I need to put in data.name let's put in a dash data.size and let's put in bytes so please work what's it complaining about now it's still complaining how it works server code refuses to work come on, I thought I changed that maybe I was mistaken for file in files I'm not constructing I'm not constructing a case class there we go okay so now it works that it works the first time it compiles which is interesting for AJAX client server application when I when I type things in that's not the most interesting part the most interesting part is when I type things in and you look at the contents of the AJAX calls are now sending nice format to JSON back and forth so I mean think about it logically what we have here is you have a client server API in the first places the client server API lives in some Google Doc or some spreadsheet somewhere these are the AJAX calls I support but we think about it more deeply what is the client server interface the client server is an interface which is shared between client and server in Scala interface is a trait and I put the trait in the shared folder and so my client server interface actually lives in the code like this name is not special I could change API to be cow or my client server interface the name is not special what special is that because the interface is shared the compiler can check both the server and the client and make sure it lines up and if it doesn't line up the compiler will yell at you and what's also interesting is that the compiler and IntelliJ don't even know that it's an AJAX call as far as the compiler IntelliJ are concerned these are normal method calls across modules the macros turn them into AJAX calls but the compiler can type check them without any extra knowledge of what's going on and if it doesn't line up the AJAX call will be well formed so let's go back to slides so that's what I would consider optimal client server integration mostly for safety the boilerplate is a bit annoying but it's O1 boilerplate which can support O and different operations so it doesn't increase as the size of that application grows take aways wiring in the existing project is pretty trivial minimal integration in an optimal configuration, sharing code between client and server is awesome you have shared constants, shared algorithms so serialization for the AJAX calls from sequence of strings and sequence of file data of strings is all handled by the UPicker library which is a shared ScalaJS ScalaJVM library so I can guarantee that it will always behave the same way on both sides the Scala tags library is shared I need to define file data case class do I put in a shared folder and define it once and it works so this is really nice and it's something you don't get traditional web development type safety which makes shared code awesome is also very nice so if I come here and I try to do something stupid on my client I try to do a new server or server.something it doesn't work the compiler and even the editor know that the server does not exist in the client and if you try to do it, it will refuse and the whole setup actually works so this wasn't a pre-screen, pre-video demo I wasn't keyboard syncing to a pre-recorded video I was actually doing it and it actually does work so to wrap up so ScalaJS works is usable for all sorts of different projects you can make games, you can make oh one thing I didn't show you earlier let's go back all the way here we have worries bad coding I didn't show you the raytracer which is a cute demo of things you can make using ScalaJS you can make games, you can make visualisations you can make client server web interactions you can make NodeJS modules you can make Chrome plugins, there's a Chrome plugin an app store made by one of our community members so this was copied from a python it's a translated to Scala and it worked unchanged in ScalaJS it's about 250 lines of Scala to implement the raytracer and I think it's very pretty, it's quite nice so back to the back to so the experience is pretty nice I showed you what it's like reloading reload time is not terrible the computation time is annoying but okay the library is kind of bloated but 100 kilobytes, 200 kilobytes is acceptable and the future in terms of what we can do is pretty nice so the number of so-called eternal web development problems that we can manage to solve with ScalaJS is actually pretty interesting so things like shared code between client and server interesting not interesting and easy to do to a point of almost not interesting almost a bit boring just put in a shared folder it works check interfaces between client and server it's something that we also have client-server interface just interface in a shared folder boring and works same shared language between client and server you could use Node.js if you want to share the language I would rather write less JavaScript and you get a whole program check client and server such that when I change the server to return a file data object instead of a string the compiler will trace through and check here on the client you're not using it correctly here on the client you think it's a string program which is probably what you want and this isn't some hypothetical future case it's not like you have to wait till Apple, Mozilla, Google and Microsoft all have to get together and make a perfect internet for everyone this is something you can use today it was actually in pretty good shape 6 months ago but in today it's even better shape and you can rely on the compiler to deal with a lot of messiness for you still reaching out to do messy things as necessary but otherwise staying within the typesafe world not everything's perfect the community is small I would say there's between 10 and 100 people using this in production so it's not like we can say Twitter has been using it for 3 years and it's great it's still a pretty new project so the SCAR compile is very slow and SCAR standard library is bloated so incremental compilation helps a lot for the compiler slowness but it's still slow and the dead code elimination helps a lot for the standard library being bloated but it's still much more bloated than say the closure standard library which compiles to 70 kilobytes of javascript without anything fancy at all we don't have any big corporate backing it's not the dark team which has more people working on the dark IDE than we have working on the whole SCAR JS project it's just 2 guys in EPFL and a bunch of extras like me who chip in whenever we can and there's some rough edges I think javascript has lots of rough edges if I keep painful edges so maybe it's not too bad but it's not perfect and it's definitely a bit less mature against SCAR on the JVM so to wrap up while some people are dreaming of the world where this doesn't happen the people on the SCAR JS mailing list have a world where it actually does what you'd expect so if you guys have experienced web development before and you think it sucks and you think it's stupid SCAR JS land, for many cases we actually have done better we fixed a lot of these problems using the compiler and using the tech system to help us and if you want to take advantage of all these things, you can use it today so that's it thanks