Clojure: A live Demonstration of Simplicity That is Production Ready - Nir Rubinstein

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

s/Vim/Neovim but the video was interesting. Thanks for sharing.

👍︎︎ 2 👤︎︎ u/-romainl- 📅︎︎ Apr 13 2018 🗫︎ replies
Captions
I am neon for maps flyer I've been there for the last five and a half years which is almost from the beginning they have been doing closure for as a living for the past five years so like at the reversing summit a couple of months ago of which I came to me and talked to me and said me listen when it is something about closure in weeks and I said closure weeks if you'd like a scholarship and what's said yeah yeah were some guys doing some closure and said okay I'm gonna come over so I'm here and so yeah and the rest is history so he told me as well this is coming and I saw his lecture before and I saw it covers all their all the basics of what is functional programming in closure and I thought to myself well I've got nothing left to talk about so I'm just gonna code a bit okay so what what do you usually do when you approach a new programming language what I usually do and I try to spin up a web server right that's what I usually do how do I spin up or up so let's see how many lines of code I can spin so that's what I'm gonna do now enclosure wear a funny not funny a simple story which relates deeply to what does well does mentioned in his talk when we were at the beginning of the of website everything was written in Python okay so we're a Python workshop for the entire first year and then as we grew at the beginning it was just the two co-founders one of them was my friend is my friend still is the CTO and and myself and don't like a year down the line everything was written in Python read micro-service architecture and messaging and everything was hunky-dory and stuff started to break because the scale grew right now a flower is like 330 people and 13 offices around the world something like that and we knew we wanted to to add another programming language to the Arsenal and we knew it needed to be functional why because that's where does the tracking of mobile ads and we knew we're going to get a lot of info coming into the system and the best way the easiest way to paralyze walk on massive data structures or massive data is using functional languages so for two months min reshef were sitting in the office we're doing some Python code but like 50 percent of the time we didn't fight on 50 percent of the time we were evaluating functional protein languages we've tested their language their Haskell and Scala and whatever and after one month in half two months the candidates were either Scala or closure basically for the JVM right because the JVM is like super rich environment and it's got all these libraries an ecosystem but closure one and and there wasn't really any debate and and the reason that it did it one is because closure two takes the functional programming paradigm and puts it to the extreme like in Scala we can do both ways right you can be all you can be functional usually what happens in most companies the transition from Java to Scala is that they start writing Java in Scala right that's what happens it's gonna name for it scheduled Scaccia okay sounds nasty so it sounds like a disease so so we wanted we wanted something that will for us force us to think differently so we chose closure so let's see I'm gonna demonstrate a bit how I code day to day enclosure how we spin up like a new project and new environment and stuff like that it's gonna be super easy go easy on me it's a live demo probably stuff will break but let's go so learning again is the Deaf actor to love integrating with with the closure there are alternative this boot and now a closure 1.9 comes with its own command-line tools blah blah blah blah then again is the defect at all so if I want to create a new project Lane new this is me creating a new project let's call it in the awesome name web okay wait for it wait for it that's it I've got a new project so let's go into the library and let's make it nicer this is the directory structure doesn't say a bit I'm going to edit something very nice yeah so it does a lot of stuff we'll see what what what else it does so this is the core of every closure project is a project clj file ok and this clj file states everything about your project but most importantly here are the dependencies so we see that this closure project in order to walk it needs closure this version that it needs one point eight point oh one point 9.0 is already out but we're using one as 800 and we're going to use I'm going to add another library which is called HTTP kit there are some libraries of doing web development in closure there's a ring and it's got like it's on a jetty wrapper and there's HTTP kit and some others I'm going to demonstrate with HTTP kit because it's super easy but you can use whatever you want because most of them follow something that's called the ring interface or the ring architecture how we communicate between each other inside the code so this is my dependency HTTP kit okay so what I'm going to do now I'm going to open up my editor because I'm super cool I'm doing it in them even though the de-facto editor of closure is what Emacs okay the defect editor of closure is Emacs so so let's talk about about tooling a bit so most of you come from the from the Java world of the skull award so IntelliJ IDEA has got a plugin called cursive it supports closure it is for closure most of the people that do closure for living usually do it in Emacs because it makes is written in Lisp and closure is a lisp so it's easy tooling around lesbian Emacs is easy I do it in vim because I like them so that's it and then the second thing i do when i when i open up Meritor i'm gonna spin up the repple okay so maybe this is the most important thing about closure closure I like to think a bit of it as a rebel driven development environment okay so I this is how I walk I've got my my editor here sorry this is I've got my editor and I've got my rapper some people like to combine them into the same in IntelliJ you can put the editor inside there the intelligence stuff like that I like to have them separate but that's me okay so that's how we write code let's go to the sauce and the Lanigan created a single file with a namespace called web dot core okay it also created the function foo that says I don't do a whole lot it receives a single argument of X and print line the X let's get rid of it okay so we said we wanted to do some web right so let's add our dependency so what I want to add is a dependency to the HTTP GET server okay so I'm doing org HDPE kit dot server and I'm aliasing it as s so don't have to write the fully qualified name space all the time it's super easy up until now okay so I'm saving let's get rid of the warning here because it doesn't really matter so what I'm doing if you look down at the at the bottom it says I'm running some tests I don't have any tests running but what I'm actually doing behind the scene I'm sending this code to the repple okay I'm evaluating this s expression in the ripples so if something breaks it would have told me if if I if if I added something like that doesn't exist when I run it I'll get some exception the exception is I don't know what org HTTP kid services I know what or gauge the picot server is okay so everything I'm doing I'm sending to this rebel here my environment is configured that when the editor spins up it knows how to find the correct repel it connects to it so whenever I'm striking some keys in Meritor it's sending the form to the repple okay so we want to create a server right so as as well as told you let's define a function deff an is how you define a function and I'm gonna call it create server it receives those no arguments and what it's going to do this is all the functions that are under the alga Jada Pinkett server namespace I'm going to do run server okay so let's look at it a bit more run server receives a handler and this is how you destruct a map and these are the options for the server so I'm not sure what the handler will be but let's write it right and the options I'm just going to give it a port okay so if my detour now tells me listen mister I don't know how to resolve the symbol handler because I've written something that it doesn't know so let's define a handler a handler a ring handler okay and the ring again is the interface for web in closure is something that receives a request and returns a response and a response is a hashmap I don't know if you remember as well just to show you a slide of it let's do it live I'm gonna return the hashmap that's gonna have a status of 200 because everything is hunky-dory it's going to have some headers and the headers are going to say that the content type is text HTML and we're gonna ask somebody let's say we want the body to be I do remember how to do some HTML okay so this is me okay so I've got here two functions one functions create a server and the other function is what the server is going to use as the actual handler okay so what I'm missing is another simple function that's a function to stop the server it will receive a server as the argument this is how you stop a server of HTTP GET the the the actual code doesn't really matter just what matters is that I've got the function here so I've written 13 lines of code that's not a lot right it took me like two minutes five minutes with explanations and I've sent I'm always sending the code to the repple so let's do the repple a bit okay so right here I'm in the repo and what I want is to use this namespace the web dot core namespace that I've defined so let's use it require the same thing web dot core I'm going to alias it as the brilliant and now we want to start a server if I do a tab completion it was it will stay it will list all the functions the public functions in my namespace so the function that I want is the create server enough credits server so right now I've got a server running on port 8080 let's see brilliant okay so this is me live coding let's let's stop the server and see that I'm not bullshitting okay okay if you think a few things to note here let's return to the to the editor thirteen lines of code or get you the Pickett HT Pickett is a wrapper around the net II server okay that means it is production ready okay you can use it for production we are using some kind of variants of this code with a lot of functionality behind the scenes but the basic entry into our systems of all our web handlers all of web methodology in EPS are looks something like this okay so this is how you do production great web handlers in closure in five minutes that's not a lot and that's like 13 lines of code okay that's just the basics what I'm trying to say here is I'm trying to demonstrate a few things first it's really easy to get started with closure because closure unlike certain languages or methodologies closure doesn't promote the ideas of a framework okay we don't have a framework for web or a framework for database access or whatever right closure if it promotes the concept of composition of function it also promotes the concept of composition of libraries okay so if I want to use this library for for a serving web I use HTTP GET this is the only thing that this library does it knows how to serve HTTP calls okay if I want to do something a bit different like Eid like route management I've gone I'm gonna need to either do it on my own or add another library right because again the same content at the same concept every library deals with its own idea like it's a single responsibility principle a bit bigger okay so this handler is kind of stupid right it doesn't do anything and it receives all the calls and if I want to do some some nifty a rotten logic behind it I could take the request and start looking at the URI inside and start looking at the method inside and start writing some functions that if say if it's this kind of method and this kind of view all right and do this if this kind of method then this kind of view right do that I can write sorry all this code on my own but I don't need to because I've got a library for it okay so let's go to the repple for a bit and go back into the project and at another library and spin up the repple again so composure is the closure library that mostly deals with routing okay and let's see how that goes so we'll add composure here all right so let's say I want to do some routing how do I do it what refer this yes refer refer look when you require stuff from other closure namespaces you have two keywords that you can use as is an alias for the entire namespace as a single whatever you want to call it okay and refer takes only these functions or symbols from this namespace and purge them into your own namespace so you can use them without any prefix notation okay this is refer you can also do you can also combine they're referring this so I can do refer as if I want to I can do something like that but I don't need to so let's leave it like this so right now I'm venting something even even niftier so let's call it an app and the app will have some routes okay another thing to notice about the the brackets situation enclosure brackets make it super easy to know the scope of what you're doing if you're inside the brackets you're inside the scope okay outside the brackets outside the scope easy as that okay so I'm defining some routes but let's define the route route and let's say that it returns the same thing let's do some if the indentation and look this this is outside of the scope of the gate so I'm gonna put it inside the scope okay so what I've but I've defined now is I've defined a single route which will only answer if the HTTP method is get okay the URL is the root URL okay and I'm returning the exact same thing but let's just say that now I'm returning it from from the root what I've got to do now Steve's the app let's do the exact same thing I'm going to create a server and press save f5 and this is the exact same thing only now with routing okay so let's say I want to add another world another route that did something like this but let's say that that after the slash I'm going to provide part of the path it's going to be a username okay what name parameter exactly so I'm binding this name parameter of the path to this variable to this symbol and I'm still keeping the rest of the request if I want to use it I don't need this part as requests but if I want to use the rest of the request I can still use it and let's say I'm gonna turn the exact same thing except that here I'm going to do some string formatting okay so what I'm doing right now I'm taking so this is if I'm if this is the routing the route is going to return this thing if I'm giving it a single slash and a path single path part that's going to be bound to a symbol called username and the camera and I'm going to return in the body hi from the username with a simple string formatting okay let's see it at work I'm going to stop and start the server again so the route isn't supposed to be changed right but if I'm gonna change the path this is me okay so this is how I do routing in closure again it didn't take me that long right like a couple of minutes handling some routes usually what happens is you define some routes in closure and they will invoke some functions and the functions will do whatever business logic that you want to do the project can be a mile long and an inch deep but it can do whatever you want it to do but at the end it will always return a hash map and the hash map will always have status code the headers body if you want okay that's the ring okay so this is me spinning up so let's get rid of this so this is me spinning up a web server enclosure really really easy look at this this call let's tape it and contemplate what you've done here so I've intentionally of cry I've called this method create server even though that the HTTP heat method is called run server why because it returns something okay I'm creating a server and I'm binding it into a variable code server so let's talk a bit about state state enclosure so how do you do how do you deal with state enclosure there is no easier simple answer okay so because if I want to run my application at the end it it's it's a java application right so I need to have some main function right and it will need to do something like create some local variables let server create server blah blah blah blah blah blah blah but someone will need to hold this reference so who will all this reference again no no simple answer we can do it either on the main we can use there are some libraries that know how to deal with this whole idea of of lifecycle of state that has a lifecycle that you start and stop it examples are HTTP servers database connections stuff like that one library that comes to mind is totes you're a component another library that comes to mind is mount you can do it like I did here just create just making it with pure function and you can do something like this you can if you're in the namespace of of the web core you can define a variable deaf one's deferens is the is like deaf defining a variable but once means it's singleton okay that's it this notes that it's private that means that no one from that everyone from outside the namespace won't have access to it only people from only methods from inside the namespace and I want to call it let's call it the server and it will be an atom and its initial value will be there now none whatever okay so then I can create another function that's called the run server again it accepts nothing but what it does it resets the value of the server with this function okay so there are two way this is just two ways of doing of handling the state of the actual server you can keep it right now I'm keeping it in the repple because the ripple is a running environment of the JVM I can keep it because everything as long as I'm in the wrapper everything is alive right but if I leave the ripple this is me leaving the wrapper then i refresh the web server is dead because I'm out of context I'll spin it up again and again I need to recreate a server but then it will leave again so you can either hold the state on your own you can put it in an atom you can use some libraries there are all methods of of arguments for and against various methodologies I won't go into it just to show you that there are ways of doing it okay I mean one simple thing to I'm going to try something less bit of live coding so we've talked a bit about closure we talked a bit about libraries in the notion of composability and single responsibility we talked a bit about state and the ways of maybe dealing with it I've thrown a lot of stuff in the air but stuff is out there you can look it up on your own and let's look and we talked about a bit about ring right the architecture I'm gonna do my last life code exercise for today and I'm going to write the middle work okay so what is the ring middle or ring winner work is actually a function okay it's a function that can alter the way that your application works okay I'm gonna do a super simple exercise I'm going to write a ring middle of our that gets rid of tailing trailing black back slashes okay because most of the time let's do this again just a second so this is her hi from near but if I had a trailing backslash too near there is no route that handles it right but usually users are sometimes not that intelligent and sometimes they'll add a trailing backslash okay so if I want my application to handle stuff that also ends with running backsplash let's write a middle way to do it instead instead of writing explicit gate for username and get for username with slash get was something it was something with slash instead of doing all the time let's write a middleware so middleware receive the handler and it returns a function that receives a request why because that's how ring works ring is a handler that walks over a function that receives a request that's it so let's see what we're gonna do here I'm going to define some local variables first let's take the you arrived from the request for those of you that don't know closure for it does of you don't know closure so a request is a hashmap usually in closure the keys of the hashmap are not strings there is something called keywords the stuff that starts with the column and and they're a function of their own they're a function over the hash map when I invoke the function you are over the hash map it looks for itself inside the hash map and returns its value if it exists if it doesn't exist it will return a nil but I have a URL and the request or anything should be good and then let's see if the URI is a single flash that means I'm the route I want to check that I'm not the route some second that the URI is not equals to slash that's it so what do we have here and I'm gonna explain this bit so this is me invoking Java from closure okay so every string in Java it's got a function that's called ends with right so I want to invoke this over the URI because the URI is a Java string at the end right so this is how you invoke functions from Java you do it starts with the function itself because your closure always begin with the function okay see this is the function ends with and this is the string what I'm giving it here is a type int I'm hinting to the compiler that the URI is doing why because if I don't hint it will do it via reflection okay and reflection is costly so whenever I'm doing some Java interrupts I try to give it some type ins okay so this is the type in that says hey listen this is a string a string that's got a function it's called and we'd use that don't don't do it via reflection so what I'm anything at what I'm checking here is whether or not I'm the URI ends with the slash so note that in closure you can use question mark is the name of the world in the name of the variables which make it simple and easy to reason about and also dashes and also usually whenever you've got something that transforms from X to Y you can call it you can call a function like this from X to Y can you stuff like that closure naming is is expressive so what I want to do now I want to do a simple leaf six euro if and if I'm not root and I'm ends with a slash okay shadow this is will be the return value but if if not let's return the same exact URI but if I want to do the exact your I we doubted string slash substring exactly sobs for URI from zero to count of your I counties exclusive story subs is exclusive but I've got to take this - one right decrement this with one and then what I'm doing then let's do let's do it more expressive fixed request a sauce request so what I'm doing now I'm creating I'm overriding the request okay the request is a hash map is a hash map I'm a sourcing into the request in the place of the URI to fix your right so sometimes it will be exactly the same sometimes it will change without the training back stash but I'm also writing the URI and then I'm doing whatever the handler wanted to do before and I'm doing the I'm invoking the handler function over the fixed request and this is the return value of this function this is the middle of our I don't know if it's gonna walk what the end training slash that's what it wants to remove the end okay so how do you how do we wrap we just wrap the application the routes with the middle we're sorry so this is near without straining this is retraining and it still works this is the middle one okay life coding 37 lines of code yes okay so the question was if I don't want to do any place rewrite if I don't want to do some redirect the the the code easier here is yours you can do whatever you want because it's just again it's functions over you take a hash map when you return a hash map that's it what the handler over the fix request does it returns a hash map you can return whatever hash map you want from it right whatever logic you want this is just my example okay so you can do whatever you want with it you can do the routing you can do whatever you can even override you can the sauce over the request not the URL you can do like a different DIF different thing a different parameter and do whatever you want with it down the line okay this is not clean closure code why because I've got a lot of junk here probably the middleware shouldn't reside within the context that deals with web probably the middle should resign in the middle world namespace and stuff like that but this is just to give you a taste of what you can do with closure how easy and fast and easy easy especially easy and the parentheses are not that once you've got like rainbow coloring and stuff like that it's all nice and fluffy like unicorns how are we stuff represented in closure in Java that was the question right when I compile it in bytecode so most of the time I know because I wanted to know a lot of the time I don't care I don't care a lot of the time I only care if I see some performance issues or stuff like that I can do whatever I want I can put profilers inside and look at the method invocation and see the pain points no problem it's a job application par excellence questions yeah so the question was do I found the the flexibility of closure or problem in regards to libraries coding and stuff when you're small it's easy when you're larger it's more difficult but if you've got good probable coding standards and methodology it alleviates a lot of the problem the dynamic typing is both a blessing and a curse right because if you look at the code if you look at the code I don't know what the types are here like I know that there are functions and I know that there are hash map I don't know the contents someone can add someone can remove someone a lot of people can do a lot of harm but usually if it's a smaller project it's okay we try to keep in Apps flyer it's a micro service architecture the same way that everybody does it so we try to keep the project small but even as the project's grow larger with sometimes sorry yield to maybe defining schema over data types using either schema bye-bye prism or or the new schema library of closure what closures back yeah it's still that the closure closure 1.9 for newbies is officially doubt but spec is still in in alpha phase doesn't really matter because you can we still use it but a lot of the time I find that the schema library by flume at it was prismatic but I think they rebranded it diplomatic for me it's a bit more idiomatic at the moment so most of the time we use that if at all because if the project is small and you've got some some remarks or notations and stuff like that you usually in the save some but I agree that as you grow larger it becomes a hazard so right now the big project was that we're going to walk on at the beginning of this year 2018 is we're going to have a unified message format that combines that goes through all of our services we started work on it like sometimes they go conceptually but this year we're going to do but I agree it's a pain point again a pain in the hazard and a blessing then it's the but it's the same way for all dynamic typing right you write code in Python you write code in Ruby you write code in Erlang in the liquor it's the same thing okay dynamic typing is both a blessing because if I want to write now convert a JSON object into closure map I do it with the function single function call I don't have to create an object and map all the fields and whatever but again so the question was what did we did we did run into some production serious production issues because of the name typing no and the simple answer is because we have tests yes but mostly we rely not only on unit testing which is good on their own end we usually do a lot of integration tests and end-to-end tests which tests the entire either service or flow as a unit okay so that's how we do it the question was if I sometimes find myself writing tests that the compiler could have saved me if there were types usually note usually no if I if I come to that point I usually define a schema okay if I come to that end what were the biggest wins for us when we move to closure well we were multi-threaded because in Python you've got the global interpreter lock so you're not multi-threaded but I listen it it's it's not it's we haven't transitioned an entire company from technology acts to technology to closure when we move to closure which was just two guys it was me in this video so it was easy so everyone that came afterwards he knew yet to do it enclosure so yes there's a bit of a learning curve yes it's a bit more difficult but after like right now we've got an extensive training program that runs almost to two months of doing stuff in AB slurry including a big emphasis on closure and after two months people are proficient enough to start writing and fixing and doing so okay even even sometimes with with junior developers it's even easier because they don't have this entire baggage of all of an imperative programming of a decade you know sometimes stuff like that of but I I had some closure code in epsilon that had something with Dow data access whatever anything people that came from the job world sometimes wrote stuff and we try to refactor it all the time to get rid of these namespaces that our controller or Dow or whatever or whatever thank you [Applause] you
Info
Channel: Wix Engineering Tech Talks
Views: 43,096
Rating: 4.8961749 out of 5
Keywords: Wix Engineering, Clojure, Nir Rubinstein
Id: LcpbBth7FaQ
Channel Id: undefined
Length: 45min 39sec (2739 seconds)
Published: Mon Dec 25 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.