ClojureScript: Lisp's Revenge • David Nolen • GOTO 2013

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay so this talk is called closure script lisps revenge I've actually given a version of this talk a few times this one is actually gonna be a little bit different some things have happened in the closure script community which are very exciting that I'm happy to be able to share with you today in fact enough stuff has happened where maybe I should have retitled this talk closed your script tawny revenge I'm not sure if all of you are familiar with Tony Hoare but by the end of the talk you will be so I I'm sure all of you know about Lisp to some degree but I'm gonna give a brief brief introduction anyway so John McCarthy invented Lisp in 1957 to solve the problem of artificial intelligence and this was because he sort of surveyed programming languages and he decided nothing that was available was good enough to tackle this very interesting hard problem so he invented lists but at the same time he invented interpreters high-level meta programming garbage collection dynamic programming languages functional programming programming with recursive recursive functions and so on right which is pretty incredible for for him to do that all at once so what's cool about Lisp and I the reason I think Lisp is still relevant today is that Lisp is one of these languages that I think fits in a nice place in the sort of ratio of simplicity versus expressive power I would actually argue that most mainstream languages kind of it's a it's more of a trade-off there of course other languages that have this nice simplicity power ratio but Lisp is definitely I think a classic example of this this is a page from the list 1.5 users manual at the bottom of the page is Alan Kay Alan Kay refer to this as Maxwell's equations of software it defines eval and apply and that's pretty cool because that's all you need to bootstrap a lisp a fully functional list system so fast forward 10 years to 1967 stanley kubrick makes a film called 2001 a space odyssey and in this film appears a very capable AI named Hal 9000 which I think everybody is familiar with and it seems have amazing amazing powers but of course it didn't play out quite that way right there was a lot of enthusiasm about AI and and you know fast forward to 2013 today there's still nothing like how nine thousand but still even given that I don't think anybody could have foreseen are the state of sort of software development today I don't think in 1957 or 1967 people have really would have thought that something like the internet would have occurred or that a lot of us would be program programming distributed applications on the web so even though we're not tasked with building this ai's which sounds still impossibly hard we still have a very difficult task right we have to design distributed systems that are robust even a JavaScript programmer is actually fundamentally designing a distributed system because you have the sort of asynchronous source of events which is the user and you have to communicate in a synchronous fashion with the server and I would argue that a lot of the tools that we're using today are actually not well-suited to this task most languages were not designed with with the notion that nearly everything you would do that's interesting is going to be asynchronous and of course if it's asynchronous light very likely it's going to be concurrent so I mean I'm gonna loop back into these ideas later but let's I'm gonna do a short introduction to closure probably something you've heard of this closure is a dynamic programming language it's a list but targets the JVM created by rich Hickey it's very cool but the thing about closure is that closure targets the JVM and there are many places now where the JVM cannot run and will probably never run and so closure came out 2007 closure script came out in 2011 and Rich's idea here was that well we wanna be able to target phones and web browsers and all these places where the JVM simply can't reach now this is actually quite a not this is not a new idea in 2011 when he came out with it I mean Google had been doing this for years with gwit right they were compiling java into JavaScript you also now have typescript which is Microsoft sort of superset of JavaScript which adds types you have CoffeeScript which is really popular among front-end developers you have dart which is actually a different language as a different VM but in order for that for them to really make that work because no other browser is going to implement integrate that VM they have to be able to compile to JavaScript so I definitely see the future of the web being many languages that target to JavaScript but if we're gonna do this right if we're gonna actually compile the JavaScript there's obviously a lot of technical problems that have to be solved in order for for any developer to actually want to adopt it so one thing that funny happened with dart was that when dart came out the dart2js compiler which they which generated JavaScript you know there was a lot of trolling about this because HelloWorld was 15,000 lines of JavaScript right some people were like who's gonna use this but of course they were they were critiquing something that was very much under development I tried recently to compile hello world dart2js now generates about 40 50 lines for hello world which is quite reasonable so what about close your script what your how well do we do on this particular which I actually think is not a very interesting benchmark we generate two lines of code which is pretty cool and this is fairly recent we use the Google closure compiler and the Google closed closure compiler is sort of heavily used in the front-end world and it does dead code elimination so our dependencies are quite clean in the internal library so we don't have to generate much code if you actually type hello world as a closure script program again that's not interesting benchmark though because all the only thing that really matters is for non-trivial programs how much code do you generate for non-trivial programs and because of because we produce output that's optimized for Google closure we're actually very good and have been for a long time the other question is is it slow what's the cost so this is something that dart2js also has to deal with and they've actually done really really well if I'm gonna use a different language and this language gives me better semantics or richer semantics is there some implicit cost right I mean what are we paying for to get this supposedly nicer language this is not OpenGL this is this is this is closure script this is a port of Notch not you created minecraft he made a JavaScript very small JavaScript demo and it's purely a computational benchmark yeah you need to update about 300 points of data in about 16 sorry 300,000 points of data and about 16 milliseconds in order to get a frame rate that's good so clojurescript like I took not just coat the JavaScript which was efficient well-written and I said 10 our compiler generate code that's fast enough as fast as the original JavaScript if this is a slightly bit slightly bit slower but not enough to be interesting it's like maybe 10% okay and then another question is okay so that's cool hello world small you generate good JavaScript what about compile times like what's the cost for having this you know having a another step so here I have a closure script file open which I'm going to demo more later at the bottom you can see that we have Auto builds so we do have to pay for this the cost of the JVM starting up to start the compilation process but once it started we do incremental compilation and you can see it takes less than a tenth of a second and there's some nice things here for example what if I make this mistake I mean I made a typo this is naka this would not be a compile time error in in JavaScript right so we do we tried to a lot of errors that you would have in JavaScript disappear so function era T's are actually important in in closure script unlike JavaScript so I'm passing three arguments to bar when it only takes two let me get we get errors about that as well so this is this is quite nice fast compiled times and very accurate errors as far as arity and sorry I should turn that off but and miss named typos about function names and variable names okay can I do bug in so that's neat I showed you some debugging capability but when you're in production how are you actually in debug this stuff and this is a good source of complaints if you looked at CoffeeScript CoffeeScript for very long time said will generate readable JavaScript we don't generate readable JavaScript at all the JavaScript we produce is very ugly right it's only the only thing we try to do is make it fast we're not interested in being readable so we really to solve this problem of this going from the original source to to the compiled source so as of three weeks ago we actually have source maps and our source maps are probably better than any other source maps that are out there that's because we can actually map to production code production code is actually going to be minified it's gonna be dead code eliminated right most compiled to JavaScript compiler all they do is sorry Java scripts whatever your language does some of JavaScript all they do is they give you the source map for the first level of compilation so we actually take generate two source Maps and we merge them and that's the one we actually use so this is I'm running some core async tests which I'll talk about shortly so here we see some stuff you notice over here I curiously have CL j s as the file extension I can click it jumps me to all the places where these testing expressions ran right and this is this is this is working even though we went through advanced compilation right this is advanced compiled code and we're getting accurate source locations okay so so that sounds pretty good right every I have this I believe every compiled to JavaScript language should deliver what we're attempting to deliver and then you should say well okay this is cool this seems compelling but who's using it so like I said this is the closure script talk I wish I could have given two years ago so the story is pretty good we have about 2300 github Watchers we have 58 contributors which is really good for an open source project that's two years old close your script is the second most popular build tool so line engine is the real build tool but it sorry it's the most popular plug-in the second most popular plug-in which is really great which means that it's been very embraced by the closure community and we are seeing more and more interest because of things like quarry sink which we'll talk about in a bit there's also a very slim O'Reilly book if you know closure doing closure script is it doesn't there's not much to know the language is more or less the same it's just how do you build how do you compile programs okay so that's the pitch but like what does it actually look like what does it feel to use the system so let's look here at this so I've I can write some s expressions here oops yeah okay good and what's interesting is that this is a repple that you know just like the ripples you've seen before the difference is that I'm actually running this rebel against Chrome so what's happening is that I'm actually compiling the JavaScript compiled enclosures given to JavaScript sending it to Chrome to evaluate and then pratik printing the result so if I go like this there's an eye there's a div a red box on that page and then we're gonna see the div here so I can actually from my source file interact with the browser which is pretty useful okay so semantics so what are we giving you over something like JavaScript we actually we don't try to preserve JavaScript semantics and unless we absolutely have to the one place where we do is numerix and if somebody wants has questions about that I can ask that later but pretty much all the semantics we try to preserve our closure semantics for example zero is not fall see the blank string is not falsies you don't need to write any checks around this there are only two false values in closure and that's nail and false and that's true for closure script we have proper lexical scoping right so if your functional if you like functional programming we give you lexical scoping you don't have to deal with the crazy scoping rules that exist in JavaScript another thing that we do is that we don't have mute immutable we don't have mutable locals so a very common error in JavaScript is you set up a for loop you have a function and you're going to execute those functions later and you close over some some values in the loop and then you you you execute them later and your program is incorrect and that's because those locals are mutable and they were getting mutated with each iteration and so those those closed over variables are not the ones you expect this is not true for a closure script because we don't have mutable locals so here I can make a basically with immutable or sort of the equivalent of a mutable array here I have a helper to invoke each function I have a loop ten times I add a function and you notice I'm just recording the value of I in JavaScript this would produce ten nines and we don't have that problem so this this whole thinking about loops and closures we just do the right thing okay so the other thing that's dramatically different from JavaScript is that closure and thus closure script emphasizes programming with values so in JavaScript you have immutable values you have strings and you have numbers and we are all very happy that these things don't change right yet the rest of the language is extremely mutable and that's not true for a closure script and close your script you provide a rich group of collections that you can use as values and that's because you can't mutate them so here's a hash map I'm going to print out the hash map with a new key value pair right there and I'm gonna print out the value of X and there you go right I can modify the thing I don't know I didn't have to copy it I'd have to clone it I'm doing that stuff right this means that you don't you you can't alias all these all these problems you have around mutability you can now reason about your collections in exactly the same way you reason about strings and numbers and you might think this how're you guys doing that well remember I said closure scripts not slow so we we actually are able to write very low-level closure script and we implement persistent data structures which were really truly actually innovated by fill Bagwell and then Ricky modified them for closure but our immutable collections are very efficient so you don't have to worry in general about the cost of working with them now the other thing that's nice is that once you have immutable collections and you can treat them as values certain things are like really nice like equality right so normally when JavaScript programmers use the quality you're talking about you often have to like am I talking about value or I'm talking about identity you're always thinking which what's going on here in enclosure script it's always about values so I have to hash maps the keys were defining a different order clearly I had to allocate to different objects but equality just works and that's having done a lot of web programming that's your client-side programming that's quite nice we also ship with many collections JavaScript it only comes with objects and arrays so we actually have immutable array like things called vectors and here I'm adding four to that vector we have real sets so this is a set I'm trying to add something that's already in the set doesn't work here's another set and I'm gonna add this and it gets in there because it's not in there already if you're coming from Objective C or Java or small talk or any of these other languages that have rich collections you're used to this notion that Keys may be complex complex keys are allowed and so this is also true for closure script so this is a hash map where the key is a vector with the values 1 2 in it and I can say get out of that hash map the value for the key 1 2 when that works right ok the other thing we do so a lot of a lot of closure script is just about simplification like removing any source of accidental complexity where we can so the other thing we have is uniform iteration so if you have a in JavaScript if you want to iterate over something you have to handle objects and arrays differently that's not true in close your script we have something called first we have something called rest I can get the first thing out of a hash map out of a vector out of a list out of a set so you can uniformly iterate all day to all the collections and that's also pretty useful I can go on but I want to talk about other things closure is a not a small language it has lots of features lots of cool stuff one thing that's really great is lazy sequences so if you've followed like Java streams that are coming out or you're familiar with I don't know lazy sequence libraries or stream libraries it does pretty much the same thing here I can make an infinite list of the word go to an infinite list of the strings are whose I can interleave these to infinite streams and then I can ask to get only a hundred of those values so this is pretty cool the standard library is really constructed around lots of lots of useful sequence function so if you'd like underscore this is like underscore too and level it has a lot more functionality okay so one place that's different since again Clojure script is not JavaScript so there are lots of things that are cool um that JavaScript can't really do or can but it's a little bit more work and it's a little bit more expressive enclosures good so functions are not primitive they're actually not a primitive construct in the in the closure programming language and they're also not primitive in closure script so not only do we ship a very nice standard library we also ship all of our abstractions right so we actually provide something that's very similar to go interfaces Java interfaces we provide these protocols you can implement your own types your own data structures you can even extend other people's types and data structures through these protocols and they magically automatically work with the standard library so for example I decide I want regular expressions to be functions like I want regular expression literals to act like functions because why not I might have a list of strings I want to filter on a regular expression right and I want to write that you know in a functional way so here I've extended regular expressions to implement the function protocol and here I have a list of strings and a and a regular expression literal and I can filter I can filter it if I switch this to Matt right that's it's pretty powerful and when you look at experience closure script developers they often you do this to make working with the Dom much more pleasant okay so just a little bit more so Interop Interop is quite nice closure as a hosted language on the JVM and then very much a similar fashion closure script is hosted in j/s we want to make interacting with a host not too difficult so this is the get element by ID function I used earlier so this is what it looks like to call javascript methods here I have a capitalized function where it takes a string get the first element a uppercase it and then call substring pretty standard stuff right so it works so we actually have a lot of features that are on that are sort of on the way with Ekman script 6 so for example I want to take a keyword and I want to convert it to a CSS property so just to show you what this looks like if I go background color this is a closure script keyword I'm gonna get a camel case string so I can use it for doing CSS property looks up lookups just to break this down here I have is I convert the keyword to a string I dropped the colon I split on - and then we have destructuring assignment so this is something that's slated for xmas script 6 so I can I can ask for the first component of that split of the array and I can package up the remainder of the array in a another local variable and then I can apply string I leave the first element alone and I capitalize all the other components and this gives me camel casing but I didn't have to write very much code to do this right and it's very much in a functional style which is pretty cool ok so I want what I want to show here is that for example when I'm working with the Dom you I have all this Dom stuff and I want to be able to bring it into closure scripts abstractions so it's more friendly for me to work with the Dom so for example I want to get the Styles off an element and I want to get something that I can treat as if it was a hash map so all the hash map functions should work on this thing so here I get the computed style for an element and then I can make it work like a function as well as implementing the interface for doing keyword lookup so I can go get the Styles for the box and then get the background color right I haven't shown you very much code like all the code that I've shown you is all that I did to make this work I can also use the function oriented style where I have the keyword first and I get it I can get the width there are lots of cool combinators in the standard library I can say I want to juxtapose the width and the height so I get back a vector of the width and the height because the styles is a function and I made it implement the function interface I can have a list of CSS properties I want to extract and the Styles works just as a function so I can keep going but hopefully you see that what clojurescript is not just a language it ships enough extraction so you can make working with external libraries external api's you can make it that experience a lot nicer so this is some new stuff yeah this is a photo of a fairly young Tony Hoare and he invented something called communicating sequential processes so moving forward I think what you're gonna see I think you're gonna be hearing the words reactive a lot I think people are going to get more and more interested in Erlang because I think we're starting to understand that asynchronous programming is too hard and the tools that we currently have really aren't that great we have to we have to write too much boilerplate to do what we should consider it to be basic stuff so Tony Hoare came up with this abstraction called CSP it's very much a sort of message oriented abstraction to deal with the complexities of concurrency it's gotten really popular recently because of a funny language called go which was created by Rob pipe and then other other people that go it's quite you know whatever you might think about go the CSP aspect of go is very cool Rob Pike has been obsessed with CSP since the 80s he's been every language that he's been doing actually honestly looks like a variant of go and he talked about something very interesting in the and the 80s which was are there any interesting possibilities between CSP and UI programming and I think there are actually some really incredible opportunities there and we'll show some of that so rich icky decided that you know he really wanted to see these ideas that are that go is embracing put in in enclosure and enclosure script and so they released a library card core async which implements CSP and we have CSP now enclosure script in it and it's pretty cool so in CSP basically you have processes independent processes and they if they're going to communicate they communicate via channels and they put a message on to a channel and then the other process can read that thing the the main the main big idea with CSP is that it's a it's a synchronous communication style if I write to a channel and there's nobody at the other end then my process will block right so if I write somebody has to read so that means that the right is a narita sort of a rendezvous the channel is a rendezvous between two processes and this is actually extremely important and it's what allows you to reason about your program if you're writing in the CSP style so here I have a channel I'm just making a top-level variable I've got a helper function for rendering some HTML it's not that interesting here's where it gets interesting I have it what looks like an infinite loop right so when you write go you're saying this is an asynchronous operation it's almost like starting a thread even though we know that JavaScript doesn't have threads right everybody is this no threads and JavaScript single threaded here I can have the illusion that I can start an independent process so I say go and I say forever this is a time out channel and when the time out channel closes this can kibrik can progress and we're gonna write 1 the value 1 on to this channel that we declared up here and this will write to that channel every 250 milliseconds we have a second process which will write to that channel every second and a third process that writes to it every one and a half seconds so here you see that that that's what's going on so even though we have no threads I've shown you no callbacks it appears that that this is actually we have three independent processes happening in the browser so we see one more we see two less and we see three the least because it's running the slowest and what's beautiful about this is that down here when I collect when I collect all that data all it's simply this line right here right I'm saying read a value off that channel so I could have many writers to that channel and I can collect all their results in this process which is doing the rendering so I don't want to I could talk about this more but I want to show that this is actually useful for Less trick less trivial examples even though that one's pretty cool so I have I have a blog post over a series of blog posts where I talk a lot about this and I spent about a week trying to see can you actually use this to build UIs and if you do use it to build you eyes is it actually simpler so one thing that's actually surprising it hard to write correctly is an autocomplete combo box it's actually a huge pain to write and jQuery it's about 500 to 600 lines of mutable code and lots of state lots of you know is this flag set is that flag set dealing with ie issues is strewn across the whole thing it's horrible so this is this basically implements the same thing the same general level of functionality it's about 200 lines of code this the the previous page that you saw so quarry async actually works with II's up to ie6 right so the previous page runs flawlessly in ie6 this page that I'm showing you runs in every browser including IE 8 the only reason doesn't work before that because I was too lazy to fix the CSS it's not a not a JavaScript issue so if I go so all this stuff works like Mouse if I tab right right all this this stuff is like really even though it looks intuitive it looks very simple if you've ever done any serious UI programming what I've just shown very quickly it's actually really hard to get right and so this was done purely in a CSP style and it created a very compact program and a program that's much easier to reason about okay so I so I'm almost done but I do have one more thing so it's always funny because I actually enjoy plug-in programming with dynamic programming languages I think they're quite cool I think they're very flexible especially on the front end though I do understand that sometimes having a little bit more more guarantees is nice and definitely on the back end having static and guarantees can be really nice what's pretty cool is that that's about to be possible for closure and closure scripts so there's a very smart young gentleman Ambrose Boehner sergeant he started a sort of like a IndieGoGo Kickstarter like thing over the weekend this last weekend and he raised enough money to start to do his project in two days he's actually been working on this for two years I've been his google Summer of Code mentor on tight closure for two for two summers but it's really great so it allows you to do typed programming so you can take an untyped closure program or closure script program and you can you can add types so he this is an example so here you can see that this is Dom stuff so I can type my interactions with the Dom you should also be able to see that there's some mention of like I want a union nil and some h2 element so so types or core.typed if you use it correctly you won't have null pointer exceptions so here we have a function if you're sort of familiar with generics or if you're familiar with Haskell or standard ml you have this idea of like a generic sort of a type of parametric parametric polymorphism so here we say we're making a statement we're saying for every type we will it's a function which takes that type and returns the same type it turns out that technically this should only be the identity right that's the only function that could actually do this and so imagine I made this mistake I mean I have that I have this I said create this type signature and then I'm saying I have a function that's called my identity it takes an X then what does it do it tries to add 1 to it so it obviously can't be the identity it's not possible right cuz that doesn't work for all types so I'm going to require court type and I'm going to check this namespace so it takes a second because it's again it's a work in progress so we has to load let's the library and as the load the closure script functionality but as soon as this load is actually a lot faster so there there we do we go it says we're trying you know it gives a fairly verbose error saying you're trying to do something with numbers when you say that when you said the type was for every type so if I switch this and it's much faster because it's loaded that's pretty cool very new stuff but I think people will be using it so core type is actually already used in production there are a lot of people are investing in it actually the reason Ambrose hit his target so quickly was because there were so many so many companies and startups were giving him money do it exactly you want to call if you want to call some method in d3 you're gonna use the dot notation but you don't really have to do this yourself there are quite a few d3 in like people really like putting d3 and clojurescript together so there's prior work that's been done on this so I would just look for examples of closure script in d3 and just copy the patterns that you find [Applause]
Info
Channel: GOTO Conferences
Views: 44,081
Rating: undefined out of 5
Keywords: Software, Software Development (Industry), Programming Language (Literary Genre), Clojure (Programming Language), Lisp (Programming Language), JavaSc, JavaScript (Programming Language), ClojureScript, Conference, GOTO, Presentation (Software Genre), Java Virtual Machine (Video Game Platform), David Nolen, GOTOcon, GOTO Conference, Computer Science, Videos for Developers
Id: MTawgp3SKy8
Channel Id: undefined
Length: 32min 2sec (1922 seconds)
Published: Tue Apr 08 2014
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.