What every Node.js developer needs to know about Elixir
Hunter, Bryan
Node with its sweet-spot of quickly standing up back-ends has caught fire in dev shops around the world. Depending on your business case, that fire can yield a high-fiving “we did it!” celebration, or a charred project timeline with scorched, haggard developers. When is Node OK? When is it dangerous? What’s the alternative? Many seasoned Node developers are discovering Elixir makes a great lifeline when Node turns creepy. They're escaping to a polyglot approach: JavaScript in the browser, Elixir on the server. OK… but why Elixir? Answer: Elixir is approachable and productive like Node, but it’s much more versatile and safe than Node. Elixir is an expressive functional programming language that is 100% "good parts” borrowed from Erlang, Ruby, Clojure, Python, F#, and Node.js. Elixir delivers familiar (modern) tooling, developer joy, simplified distribution, massive concurrency, and carrier grade fault-tolerance. Curious? Good! Come join the fun!
 All right, perfect. So awesome to have you here. Thank you, thank you. We're going to talk about what every Node.js developer needs to know about Elixir today. There's me on Twitter. I respond on Twitter, so hit me there. I love carrying this conversation on out of here, and if you have any questions, always follow up with me there. There's no expiration date on that. I want to start off. This illustration appeared in the Guardian shortly after December 25, 1914, and this is an illustration of the Christmas truce, where the German and British soldiers that were a trench warfare, with this excuse of coming out and burying their dead, they got together and they were civil to each other. In the middle of this horror that was going on, they stepped out and they acknowledged each other's humanity. And in technology, tech, we often break off into camps, and we don't do that so well. A lot of times we don't reach out. And so for the Node folks here, I really appreciate you all coming to a functional programming talk. And for the functional program people, I'm really glad you're here to think about this Node side of things. At the point that we make problems visible, then you can do something about it. You can improve the situation. But until you make them visible, it doesn't really happen. And so, thanks. So this idea of civility, we might hate a technology. There might be problems with a technology. We might know that a technology is dangerous. But you have to understand how people got there and have empathy for them in both directions. So my path, this sort of long road, you can tell by my gray hair, that I began writing software professionally back in 1994. And so I was writing C and VB, so the old VB, not VB.net, but kicking it old school. And then Pascal, VB script, J script, JavaScript, and then C sharp on. And through that path, I ran into lots and lots of problems. I created lots of problems, like we all do. But I probably created more than my share of problems. And through that, I might not have been the best developer, but I was awfully good at seeing my mistakes and trying to learn from them and seeing what the pitfalls were that led me there. And through that, I worked to try to help other people avoid pitfalls. And that empathy that I tried to use in this land of imperative code and OO code during the 90s and the aughts, interestingly, it had this reputation for being able to see these problems and help. And that led me then to Norway in 2007. So I was here, was brought over for a large architectural risk assessment project. So here in Oslo, there was a company that had a huge code base. They had 20 million lines of managed C++ and C sharp code. They had these 12 architects. And we worked on this risk assessment of how is the software going to destroy the company project over the six week period. And through that, all of the problems that I imagined would be in the code base, those were there. So you could almost get Robert Martin's book and just hand that book over before you even went in and looked at the code because those problems are common across all imperative and OO systems. Those code smells are there. And so that was expected, that side of it. Amazing team, but you expected the problems. One thing I didn't expect, though, is there was a system in that shop that had been up and running for four years without a millisecond of downtime. All the other applications, they were crashing maybe multiple times a day. It was embarrassing. It was causing trouble. You had dependencies within the code that made it hard to upgrade. You had the mingling of state data and behavior, like we're told to do by Martin Fowler. We had that all through the code and that caused all these defects in the software that made it was really hard to solve problems. And we had event storms because you had concurrency involved in this. Concurrency's hard to do if you have mutable state. Problem, problem, problem. But this system, four years without a millisecond of downtime, that was unusual. And so I asked more and more about it. And I actually learned it was even more remarkable. There had been two years previously, there had been a major code upgrade, this compiled language. They compiled and they'd pushed new updates to this running cluster without a millisecond of downtime then. So I was like, what is the spooky magic? And so I learned for the first time the word earlying. I'd never heard of it. I was off imperative OO guy. And I was happy there, sort of happy. I knew I had problems and I knew there were problems, but I was comfortable there. And so I dug in and I started learning more about earlying and my code changed. And I have built systems that people tell stories about now that they've seen these good things. I haven't done that before, before I ran into the earlying VM. And so it changed my life. And so I'd like to come back to Norway and return the favor. So I'm very thankful for this city and for what it's done for me and all the defects it's kept me out of. So here we have the Hebrew's journey. This is sort of the arc that all novels and movies and everything follow, this arc of the hero's journey. And so that was the beginning of my hero's journey. And hopefully, this will be the beginning of your hero's journey as you go through and you pick up some of this knowledge. We'll go through this ordinary world and we'll progress. So for the node folks here, I imagine you came to node for some of these reasons. It's really a welcoming community. You can come in without knowing much about programming at all and you're welcome to in. And that's awesome. And it's easy to get started in node. And there's no doubt about that. It's easy to get started. And you can be working in Angular, Durandal, Aurelia, one of these frameworks. And if you need to have a back end, you need to stand that back up in quickly, well, you can do that in node. It's very easy to kick that up. Everyone sort of knows JavaScript. No one really knows JavaScript. Everyone sort of knows it. Then people will also come because they've been hurt in other stacks. There's problems with the tools being too heavy or not being able to have enough control over things, just various problems. And there is a concurrency story on node. It's different than I think a lot of people think it is. But there is a story there and people know that concurrency is important. So that brings people. And then there's good support in Visual Studio and on Azure. I think of this sort of progression in node. And I have lots of friends that went through node. I started working in node when it was brand shiny new because I was interested in the story of it. I pretty quickly then dropped it because I had already learned Erling at that point. And I saw it's like this isn't really filling the bargain that I thought it should be. And so, but this is this progression. We start off with folks that are junior. And they're full of optimism. You know, they haven't even heard the horror stories yet. They haven't heard any of the bad. It's just this welcoming community. They come in and they're excited about this. And that is a beautiful thing to have. And at some point you move on and you then have your sort of engineers. And they have heard the problems. Maybe they've seen a few problems. But the thing is, they can say, I'll be a craftsman. I see these problems. They're documented. They don't know how to actually be diligent and not run into these problems myself. And that's that tier. This is the second stage of node development. And then you move on to the seniors and the leads. And I have friends that are in this spot right now. They bought into this. They brought their companies along. And they've heard the problems. They've seen the problems. And now they're like, oh my God, what have I done? You know, they've got themselves in a trap because they used it for everything. They used it for things far, far outside of its sweet spot. And they're in a terrible place. And they're having trouble shipping code. That's rough. That's a rough spot to be in. And those folks, I'm excited about where they're at. I'm excited about all of these groups coming in because it's a great feeder into Elixir, I believe. But the folks that are senior, they're looking for escape pods. And a lot of them are joining up at the Elixir user groups around the country, so around the world. So you'll have this mix of Ruby people. And you'll have this mix of node people. And then a few scattered FP people showing up at the Elixir meetups. And so I'm really tickled about this linkage and this connection. When on node, when people talk about node, they often use the word scalable. And it's sort of a problem, I believe, to use the word scalable in the context of node. Well, scalable is a rough word. It's sort of a buzzword, marketing word. It's a word that managers like to use even though they don't know what it means. And I feel like you could say, okay, you've got a fast car. Describing a car is a fast car. You've got a car that goes and flies through the guardrails and falls down the bluff at terminal velocity. And you could say that that's a fast car, but you're missing an important part of the story by calling that a fast car. There's other things going on. And so when you call node scalable, there's an issue in that it can handle the 20,000 connections that come in. It can handle the 20,000 users as long as you immediately pass that off for something else to do the work. Because if you do the work, you then have got this issue of where you're blocking. You're blocking your other 19,999 users. So the issue then is like, okay, we hand off the work, or who's going to do the work then and what do we write that in? And there are also solutions. Every time you run into a problem, there's a lot of ingenuity in the node community, and they have solutions. You'll have things like Q. And you'll have these ways of just passing things off these libraries that have been written. But it's always hard manual work and a lot of learning and discipline involved. A lot of folks, you'll see a lot of blog posts that will say node is not a silver bullet. And I think you could say that about most technologies. It's not the thing that solves everything. But there's another way of actually looking at the problem of silver bullet. And in this sense, I think maybe node is a silver bullet. In that a silver bullet has a really narrow use case. And there's a sweet spot for a silver bullet, and that is to kill werewolves. And day to day, there aren't nearly as many werewolves running around as Hollywood would make you think. And so the sweet spots that you'd fit, there aren't as many solutions where it does map up closely. And so a more, more of an uglier view of this might be it's maybe not the silver bullet, maybe it's more like the full moon that brings out sort of some crazy in the environment. And I'm kind of off of this part of the talk. But I've seen so many of my friends hurt by this, and I believe that this is the most dangerous technology in the world. And so, and I hope that you take this in the spirit that I'm offering it, that I'm really trying to help and I'm trying to keep problems from happening. So let's now move on to Elixir and how it came to be. So we've got this history of a character named Jose Valim who is here at the conference this week to speak. And so he was a core member of the Ruby on Rails team. And he was trying to solve problems on Ruby. All the, you know, he's a good developer. He's focused on these issues. It's hard to solve problems on Ruby. Like, people would ask for scale. They would ask for concurrency. They'd ask for performance. It's a hard thing to deliver on Ruby. And so he was battling that battle. And he was then reading seven languages in seven weeks. Out of curiosity, who else heard this book? Awesome, awesome. Yeah. And so he got to the chapter on Erlang and he was like, whoa, he was kind of like everyone does when they first hear about what this thing does. And they're like, that's weird. Why haven't I heard of this thing? And so he was reading about Erlang and he saw that it fit these problems of fault tolerance, concurrency, distribution. This scale thing that he had been asked to solve. And so he started looking into Erlang then. It's like, first, like everyone does when they first bump into Erlang, they think, okay, can I steal parts from Erlang and bring it over into my stack? And there are reasons you can't do that that we'll talk about briefly. It's really hard. It's a part, hard problem. And so he's a smart guy. He realized it pretty quickly. You can't do this. It's not going to happen. So he thought, maybe I'll become an Erlang developer. Okay. Erlang is known for one thing and that's it's about developer joy. Right? It's a happy place to be a developer. They hug each other. You know? It's like a good spot. It's not necessarily known for those other things we're talking about. But it is about developer joy. Now you can see the reverse about Erlang. So it is good about solving these hard engineering problems. You've got these Krusty engineers that created the language. Two of them are here this week. So we have Joe Armstrong and Robert Verding, Krusty, Sirius engineer guys. And so they weren't focused on the problem of DevJoy. Ericsson and Stockholm, they weren't focused on that problem. And so Jose decided, I'm going to take, I've got another approach. Instead of trying to rip off Erlang, what I'm going to do is I'm going to write a new language that targets the Erlang VM. And that's the path he went down. It's like, I'm going to build developer joy, good modern tooling, all this on top of this VM that has this amazing track record. And we're going to talk now about the sweet spots. So Elixir, it's also approachable. And it's productive not just in the short term, but in the long term. So it's approachable, productive, and you have modern tooling. So first about approachable, we can look at, you go to elixirlang.org and it's a useful website. It's not just a thing because you've got to have a website. It's really useful of learning the language. And so you jump in there and you go to the Getting Started guide, down on the right here, you see 1 through 21. And you actually have a really good handle of the language just by following those pages. You can start here instead of getting a book and you'll do fine. Then as you're going through that, you can also go to this other link here and find all the meetups around the world. And you'll see a bunch of Ruby people and a bunch of node people and functional programming people scattered in. This is the pattern I've seen city by city. You can go to GitHub, see the code, see the language, and contribute. And you'll have feedback from Jose right on the side. So you have this, you get a pull request and he's sending hearts all over the place. And so this is a nice thing to see this Ruby love showing up inside of this language. He's a great guardian of the language. He's a great protector and he's also very interested in bringing in ideas from all outside places. Another part of the tooling story is Hex. You have Hex PM, it's a package management system. So you can use this for your Erlang code, which you don't have because there aren't any Erlang developers in the world. There's like maybe five, ten, you know, there are a few of us. And so there aren't many. But this Elixir side, there are a lot. And that's a growing thing. And so we go off and we see some of the libraries out here. You won't find libraries that do like three lines of code libraries. These are libraries that take on more serious things that people need all the time. But you won't have your six lines of code on a package. And also if you go to something like Ecto and look at, you'll see that the level is pretty good here. This is the documentation off of a package that you pull down from Hex. Hex is fast. All sorts of good qualities about it. Packages don't disappear on you on Hex. It's just a mutable store of packages. Packages disappearing on you. This of course has been in the news this year. Poor fellow over here, Aizer. God bless him. And so, you know, so he took a beating. And there's a lot of beating that went around. There's a lot of shydenfreude. There's a lot of negative that happened here. But I think it's comment by Tracy Harms is really nice. This catastrophe isn't the fault of a single solitary developer's decisions. And if a complete stranger can push some buttons and break your production deployment, you have some thinking to do. Especially if that was around six lines of code that was really about doing something that the language should have done anyway out of the box. Okay, modern tooling. So we'll have this sort of retro, modern, hipster, bicycle thing here. And so like all modern languages, we have the terminal is the way you do your good work. And so we'll return to the terminal here. IEX, the interactive Elixir shell. When we say IEX, that brings up an Erlang node. So it brings up an instance of the Erlang virtual machine and loads up all the Elixir goodies here. Okay, we go IEX and we are inside of IEX and we can do something like H, a noon. So help. We're going to get help on this thing. We hit dot, we tab, and we get auto completion of all of the functions within the anew module. Or within the anew, yeah, within the anew module. And so we say, I'm interested in what count one does. The count that takes one argument. I'm interested in what that one does. So we get this nice color. We get examples right in the examples. And this is the way you can go through all of the libraries in Elixir and you have this help right at your fingertips. Mix is another tool. IEX is a tool, Mix is a tool. Mix is ripped off from Clojure community. There's a tool called Line again there. You can see some of the commands we can do this. You can think of it, build code, run your tests, scaffold new projects, and it's pluggable. So additional things can come in. So let's say Mix, new, Fizzbuzz. We're going to scaffold out Fizzbuzz. And here we go. We get a readme markdown file, which is nice and modern. We get a getignore built in, which ignores that we would want to have an Elixir project. That's nice and modern. And we are config. And so when we have our Fizzbuzz module and then we have tests, I mean, this is nice. We come in here and this is a nice place to be. So let's go into CD into Fizzbuzz. Say Mix test. We compile and right out of the box we get one passing test. So they already started off for us with a template for us to have tests. So let's now go in and see what that story looks like. Okay, so I have here our scaffolded out code off of our Fizzbuzz. This is just what is... So this is our one test that was scaffolded out for us and that's why we had our one. Now I have a fully implemented Fizzbuzz over here. And we can see it's down here. We play to a number and it does a bunch of stuff that we don't have to worry about yet because we're going to see about the syntax in a minute. The thing I wanted to show here was the experience of saying Mix test. Okay, so we have three tests and one failure. So we saw one test a minute ago. What's that about? And why do we have a fail test? Let's go in here and see what this fail test actually is. So it says here Fizzbuzz play 10 to 16 and it expected a Fizzbuzz here but we had a Fizz instead. So let's go up here and see what that's about. So what we have here is this is not a regular comment. This is a doc test and so right in the middle of our comments we've included examples of usage to make it easy for people to come in and right here this becomes part of our test suite. So we have Fizzbuzz play 1 to 5, it should get this and that became a unit test. Fizzbuzz play 10 to 16 should get this and that became a unit test that actually failed on us because we have a bug down here. We have a pattern match that's too greedy and so what we need to do is move this code up here, do this and then we need to move down here and we need to rerun our tests. Oops, I forgot to save dinner. Yeah, so our test passed now that was based off of that doc test. So I think that's pretty sweet. So another productive nice sweet part of Elixir is the Phoenix framework. So this is a web framework that was built by the fellow who just walked in here, Jose Neim, created the language and Sonny Skragan who is back there and Chris McCord and there's a bunch of awesome people. Chris was here last year, gave a talk, it's on Vimeo. And so Phoenix is amazing but I'm not going to talk about it because there's a lot of good content about it by people here later today. But this is what a lot of people want when they come to a web framework. So Elixir is functional. And so we've probably heard a lot of buzz about functional over the last few years. So a simple way of looking about functional is you have inputs that are transformed by a function and you have then outputs. A goes to B, inputs go to outputs. You don't have, I'm going to come in, I'm going to set the table with all my state, I'm going to set fields, properties, I'm going to have a class, all this stuff and I'm going to call then functions that are going to mutate state and then I'm going to lose track of what I just did a minute ago and I'm going to have all these bugs. So instead you can look at the class, what came in as the input and know what should have happened inside of the function and return. This is important. And this is a good way of getting out of a lot of those troubles that I saw when I was my first trip to Norway. Mutability is another part of functional programming and Elixir takes this very seriously. It has to take this very seriously because the Erlang VM has a hard set of rules that it enforces and this is one of them. So it's not a thing you can turn off. Separation of data and behavior. So this is the thing we're talking about earlier about classes with their fields, their properties, the data and their behavior mingle together which limits the use that you'd be able to handle and use that class in. This is in Elixir you have modules that have functions. You don't have properties fields. So you call into a module and you call a function within a module and it's just the inputs that come in and then the outputs that go out. So you spawn up a new process and you say this process I need to call into this function passing in this input and I'm going to take the output of that and feed that into another function and you just pipeline these things together and that's the way you build programs inside of Elixir. So we have expressive dev joy. Let's talk a bit about the language now. So language, language, language. So we have IEX again and we're going to look at some of the types here. So we have integer, expected, OX2A, that's kind of nice. You know we get our hex right there. We don't get barked at for having seven float divided by three. It just does the thing you'd expect. The thing. You have a type called atoms that are sort of, they're the thing themselves. They're only comparable to themselves. They're just a handle or a constant that even if you have a whole cluster of different machines, this like the atom goat is equal to the atom goat on the server and it's not equal to anything other than the atom goat. Strings are real strings inside of Elixir. You might have heard stories, horror stories about Erlang where it's like, oh it's bad at strings. And it turns out it was a problem with naming, was the problem with Erlang and strings. The thing they called a string is not what people expected it to be. And in Elixir, a string is what you expect it to be. You know you get this UTF-8 binary good thing and it behaves like you would expect it to. Actually it behaves a little bit better than you'd expect it to. And we'll see that in a second. We have lists. You have lots of list processing inside of functional languages and you have tuples. So this is a positional thing. So we see that. Okay let's look at pattern matching for a second. So x equals five. So we got our five there. And we'll say five equals x. That's a little weird. So what we're actually doing here, this is a pattern match. And it's going to evaluate the same. It's happy to say, yep five is equal to x. This is a match. And you can pin x down and say pin x equal five. And it's happy to say that, you know that's it. We say pin x is equal to x plus one. It's going to bomb and say nope, no it's not. Things not equal to six. Left hand side is not equal to six. We have then pattern matches that can be against more complex structures like tuples here. So we have ABC tuple that matches against Apple Banana Cherry. And we see that we then bound B to banana. You know and then Apple and C, Apple to A and Cherry to C as well. But that's what we showed here in the shell. Pattern matching we'll have a little bit bigger of an example. We have list here, one, two, three. See it binds. Does a pattern match sort of is a way of looking at it. But we're actually assigning this thing. So list is now equal to one, two, three. And we say case our list and we're going to do pattern matching here inside of this case statement. So and we're doing this in the shell here. You can have multi-line things. You can have complex bits inside of the shell which is pretty awesome. So we say case list do we say 11, 12, 13. And this is not going to match because one, two, three is not going to match that right? Okay is this going to match? Nope, not going to match because this is a tuple. One, two, three rather than a list. One, two, three. It's a different type, right? Here we have one x three. And this is going to match and it's going to bind the x that came in. It's going to bind the two to the x in the middle and we can then use that later on in the same case statement to do our string interpolation and show this. And we'll see that happen here. So matches and binds two to x. Digit separators. This is something that's coming in C sharp seven I believe. So we've got a thousand. I also can say a hundred. I can score. I can say, da, da, da. So it's just pure candy. I mean this is about the dev joy side of the language. I mean there's just all these things that just make life a little bit nicer. It's not important but it's just awesome though. It's thoughtful. So here we're going to look at enumson streams. So we're going to define an anonymous function. So a lot of times in functions if there's a convention of if it returns a true or false you can put a question mark at the end of it. So that's a nice convention. You see it, you know what to expect. So we're going to define this anonymous function that's going to use the rim function. So rim returns the remainder of two numbers, you know, divided. So this is like a module. And so we say rim, the first argument, so the ampersand one is going to take that first argument that's passed in. It's going to rim that number, comma two, so we pass it in a five. Remainder of five, comma two would be, well, one. And so it's going to be an odd number, right? So here we have a range. We have one to a hundred thousand. And we're going to pipe this forward. So any F sharp people in the room? All right, you'll recognize this. So we've got one to a hundred thousand piping forward into so that each one of those values are going to get pushed in as the first argument to the thing on the right. So this functional pipelining. A new map, and we're going to take whatever the argument was, we're going to multiply it times three, and we're going to pipe that forward into a new filter. And we're going to filter on our odd function that we defined at the top. And then we're going to enum sum that. And we get our answer. Let's do the same thing, but this time we're going to use stream.map. Stream.filter. And then we do enum sum. So the difference here, we get the same result. The difference is, is stream is lazy. And so on our first and our enum, each stage of that, we went through the whole computation and we passed then that on to the next series in the pipeline. With stream, it's dragging one at a time as you're coming through. It's a pull-based thing. And these both work off the same interface. It's called a protocol that they both implement the enumerable protocol. This is like interfaces in C sharp, or the protocol comes from closure, where this idea is directly borrowed. I mentioned strings earlier. This is kind of cool. We can have straight up UTF awesomeness right here. So all the Norwegians with funny characters in your names, you can appreciate this, right? Person equal. So let's look at maps. So we got our person name, Brian, beardy false. I'm only beardy in the winter. Not beardy in the summer. And so we can access it by key, like this. Person name, you can access it by dot, like this. Get the same thing. We can build a new map based on an old map and just push in the properties or the keys that we're going to change or we're going to override. And so we have then same thing, Brian Hunter here. Okay, let's look at structs. Yes? In that part, did you still reference the old object? Yep. Yeah, I could do person and it's still there. It's just that we have a new, everything's a copy. There's, you know, it's not mutating. So good question. Here this builds up on top of that idea, but gives us some extra goodies. So we're going to define this module called person here. We're going to put a def struct in here. We say name, and we're going to give it a default of empty string, and we're going to say beardy and it's going to default defaults. And we then have this data structure that we can start using. So I say a person. I get my defaults. I'm going to say Brian is equal to a person named Brian. So we see person, beardy, false, named Brian. I say person, name Brian, barty, false. Boom. There's no such thing as barty. So we got protected by using the wrong key there. There's no such thing as barty. There's beardy. So it blew and barked and kept us from getting in this all sort of trouble that you've probably all experienced with JSON. All right. Versatile. This is a really crazy thing. So the language, you expect certain things out of languages. Here we have something you would only expect to be able to do in C. So we have the bit syntax and we're going to run through this really quickly. We're going to grab OK BIN data and we're going to read this file. So if we look back on this image, this is a five pixel wide black, red, green, blue, white, and this is the data below. So we're going to read this file, capture it. We capture BIN data. We capture the binary data there to the BIN data variable. And we're going to set up a pattern match where we're going to catch on the left using this DSL called the bit syntax. We're going to catch on the left the data if it matches against BIN data here. And so we'll see how that worked. So here's our data again. Our left two bytes has to be BM in a bitmap. So you can just go through and just think about data, you know, binaries out there and you can just implement using this DSL and be able to process like whatever your protocol is that you're trying to implement or your format. So that was a match. We're going to throw away 64 bits. We're going to capture 32 bit little Indian into a variable called offset to pixels. Throw away, grab five, height one, size we're going to throw 16 bits away. We're going to make sure that the next thing is a 24 here. And then we're going to throw the rest of it away. Now we're going to say that offset to pixels. This told us where the actual pixel data begins. And we're going to remember that and we're going to throw away that many pixels. And we're going to capture the rest of it into a variable called pixels. We do that. So we saw our values that were here. So we have this four comprehension where we're going to capture, we're going to shove pixels in eight bits, eight bits, eight bits into blue, green, red. And here we go. We've got our data. So that's one line, one screen worth of code inside of the shell and we've, you know, parsed bitmap, which is kind of awesome. So something borrowed, a lot of things borrowed. One of the things borrowed is Erlang VM. Erlang VM grew up out of Erxon doing awesome, serious hardcore telecom things that were focused on fault tolerance. So to have fault tolerance, you have to have concurrency. If you don't, process dies, you're fully down. You have to have distribution. If you don't, box catches on fire, you're fully down. So those things are important. When you see the track record of, you know, in fact, your phone works and that over half of the world's mobile traffic is going through Erlang, which is pretty incredible, the data text voice. More recent story is WhatsApp with their victories on the Erlang VM. You know, so just amazing, amazing numbers here, a billion active users a month and so on. And another number that's important to the business is $19 billion that they were paid by Facebook. There's 10 engineers building this mighty code base. We look at what the Erlang VM is in context. We have the runtime, we have OTP, we have languages Erlang, Elixir, List Flavored Erlang. There's a talk here this week on List Flavored Erlang by Robert Verding. And so here's why people can't just grab the Erlang VM, like Erlang bits and pull it into their language. It comes down to this thing as an operating system. And it took a lot of time to build it. It's a serious operating system. It's not a general purpose operating system like Linux or Windows. It's a special purpose operating system about making a safe place for code to run. 250 plus years of development went into it. You can see an example of it being an operating system on Erlang on Zen, the Zerg demo. And this boots up what would take 300 seconds to boot up a Linux VM on EC2. Here they boot up into an instance of bare metal Erlang running on the Zen hypervisor. Boots up in milliseconds, brings up the Erlang VM, runs a web server, processes things, kicks out your request, and you have this result in.3 seconds. Pretty awesome. So let's look at the job of an operating system, which Erlang VM is, process management, interrupts, memory management file system, so on and so on. And think about what our code does, our C sharp, our C, our JavaScript, has a job. And that job is to eat as much core as it possibly can. It's trying to do, it's only worried about itself. It's not interested about the safety of the rest of everything running on the machine. And so the operating system kind of has to hate you. It has to hate your code. It can't trust it. And this is the place where it's really different on the Erlang VM is because the Erlang code cannot do things to hurt the stability. The Erlang code itself has to play by the rules that the Erlang VM set up for it. Erlang VM doesn't have to support C and Java and Ruby and all these languages. It supports languages that only are going to do things that the Erlang VM allows them to. So that trust is nice. When you can cooperate, you can get a lot done. When everyone's fighting against each other, you don't get a lot done. And so this is a big part of that story. So we got our Shaun of the Dead reference. We'll get back to processes. So processes is the way we win here. So concurrency. Concurrency is not the same thing as parallelism. A lot of times those words get used interchangeably, but concurrency is about the structure, doing lots of things at once, and parallelism is about the execution of lots of things at once. This comes in on a story at Ericsson. So when they built Erlang in 1986, they weren't targeting multi-core machines in Stockholm then. This wasn't a thing then. And so they built concurrency, and they didn't build it so that it could go twice as fast. They built concurrency so that they could code without getting twisted up into these horrible nests of callbacky weirdness and into thread weirdness. And they wanted to make the code simple to read and to write, because code that's simple to read and write is less buggy. And that helps your fault-tolerant story. So they did this massive moonshot from 86, and then they turned on multi-core in 2006, and code that had been written a decade before, it did then run twice as fast on two cores, four times as fast on four cores. And like 2010 or 11, there was a test where it had linear scaling up to 40 cores on properly written Erlang code. We get that same thing in Elixir, because it's the same VM, all compiles down to the same beam. So let's look at Elixir and the Erlang VM and the Actor model. So every Actor gets some props. So our Actors are processes. So every process gets these props. One is memory. So each process is one kilobyte on a 32-bit machine. It's two kilobytes on a 64-bit machine. Inside of this memory here, we have a heap and a stack, and it's that process is only. No one else can reach in and grab a reference to memory inside of that process. It's isolated. And it's also immutable, right, because it's functional. And so garbage collector, easiest job in the world to be a garbage collector on the Erlang VM, because no one's, only one person's looking at the memory. You can't change it once it's set. And so each of these processes, they get their own isolated, dedicated garbage collector. So there's not going to be a big stop to WorldGC that happens. Each one gets garbage collected independently, which is pretty amazing. And that's done for low latency, and it's done for deterministic scheduling. Our mailbox, this is the only way a process talks to the world. So last four, Yorick. So we talk to the world through our mailbox. This is the only way a process can reach out. And so we send a message out of our mailbox. We address it to another process. It makes it an NSM box when they go into a receive block. Links and monitors is the thing that we build up on to create some fault tolerance goodies. This is at this OS level, this Erlang VM level, where we get links and monitors, links, basically like I'm going to link to Jose over here. And if Jose dies, I'm going to die with him. Okay? Sunny back here, and there's a different sort of thing. So I'm going to monitor to Sunny back here. So Sunny dies, well, I don't really exactly want to die, but I'd like you to tell me about it. I actually care about him, but I don't want to die. And so it's a different level of commitment there. And so that's these two tools you have out of the box. So process scheduling on the Erlang VM. We have a CPU core. We have a single scheduler that lives on that CPU core. Get three processes up. And each one of these processes is going to get 2,000 swipes at the core. 2,000, 2,000, 2,000. There's nothing in the world they can do to eat more core than 2,000 swipes. They can't block and hold up to show. Everyone gets preemptive scheduling here. So this is another way of visualizing it. They each get this much, and they get thrown back into the rotation. Same thing happens if there's multi-core. If there's big multi-core. Yeah, all happening. So we also have the supervision bit off the links and monitors it's talking about. We have a supervisor and a worker. The worker, something happens. The network card's down. The hard drive failed, whatever. We have some weirdness. The supervisor can then restart the worker. And this is important because what do you do when you call tech support about something, the story is reboot it, right? That's the first thing they walk you through, and it always works. And you're like, oh, it worked again. And so this model is built in to Erlang. It works so well for tech support that they included it as part of the language. So process running, the process running, and boom, he falls into a receipt block. He's going to sit here forever and ever and ever blocking, waiting for a message to appear in his mailbox. No one's talking to him, so he's going to sit here. Well, does that wreck the show? Have we now blocked and wrecked the show? Well, no, we haven't. Because the Erlang VM schedules him out of the mix, and then we schedule then across the other two remaining cores, back and forth. And we don't bring this guy back into the mix until the postman, the Erlang VM, the operating system, until he knows that that process actually has mail. When it does, he's brought back into the fold part of the rotation. This includes things like file I.O. So any sort of I.O. that we have goes through message passing like this. So even though I write file read earlier on that bitmap file, when I said file read, I was talking to another process, and then I waited for that process to send me a message back. I didn't have to do this as a developer. It's just part of file and the read function on there. It's part of GenServer. And so at the point I asked for that file, immediately when I asked for it, that process over there doing the file reading, and I'm removed from the rotation until I have a message in my inbox. So non-blocking I.O. that you don't have to worry about, you can treat like sequential code. It's really done right here. Core cores for schedulers, you got processes, and we have this game of balancing compaction that happens. And so busy scheduler, busy scheduler, I'm not so busy. I'm going to take some work from this guy, move it over here, so if this scheduler can get sleepy and the whole core can go to sleep. And this will happen so that you get this compaction across your cores, and in a server closet you'll have half your cores being able to go to sleep if they're running early, which is pretty amazing for power savings. This core, memory locality, things are building up here, he's getting hot, hot. This one's got some work stealing to make it even even balanced. So get this game where we play and we get massive concurrency, primitive multitasking, soft drill time, low latency. And the low latency is valued more than raw throughput, which is an unusual characteristic for a language. Scheduling, parallelization, and fault tolerance in Node, because you're pretty much left to your own devices here. I mean, things, you know, you're going to build your own operating system, every project, or use something out there that someone else has had to do. So on Node we have cooperative multitasking, and on Elixir we have preemptive multitasking. So cooperative multitasking, it sounds good, right? But what it means is you have to cooperate, and if you don't, you can wreck the entire scheduling system. On Elixir you cannot do that. Single threaded event loop. Single threaded event loop, cooperative multitasking, it's like they read my mind. What we do when we're, you know, we get into this trouble with callbacks, and I know that this is one that you've heard a lot about, and there are a thousand blog posts out there saying there's no such thing as callback hell, it's a myth, and all this. But a lot of people are talking about it, so it's some people experience it. But there's discipline, you can follow all these paths, you can go down this route, and you can solve your callback hell problem and have flat code by hoisting things around and flattening things out, and you know, on and on and on, and all these patterns if you're a diligent person. There's a funny use of words in Node, but we'll talk about that in a second. So Node.js does not automatically manage the number of workers for you, however, it's your responsibility to manage the worker pool for your application needs. So Node's easy, that doesn't sound easy. Distribution tends to be very unbalanced due to operating system scheduler vagaries, loads have been observed where over 70% of all connections ended up on just two processes out of a total of eight. Well, Node's supposed to be easy, that doesn't sound easy to me. Okay, here let's talk about Elixir and simplified distribution, and I think I actually do have time for this demo, which is really awesome and surprising. Okay, so here we have just a simple loop called blabber, and I'm going to move over here and then use, I've got three consoles, a terminal window set up, and I'm going to start up an IEX, and I'm going to pass it S name cat with a cookie of taco. Here I'm going to start up a IEX with the name of dog with a cookie of taco, and here I'm going to do bird with a cookie of taco. So I've got these three named virtual machines, these three nodes brought up here. Okay, and if I say node list, I don't have any friends yet. So I say node connect, and I'm the cat, so I want to connect to the bird, and it says true. So if I say node list again, I see this, the bird, he knows that something's happened too, and he's like, uh-oh, the cat knows about me, so I'm going to say node, not connect, and I'm going to bring the dog into the mix because the dog always saves the cat, or saves the bird from the cat. So here, and I go back over here, and do my node list, and I'm like, oh, so we all know about each other at this point, so we have a full mesh between these nodes, and that's all it took to do this. This can happen across multiple boxes, across heterogeneous hardware, so 64-bit windows, 32-bit Linux, a Raspberry Pi on ARM architecture, and we can have code this cluster formed, and we can deploy code across these. So the code I'm interested in deploying here is this blabber server. So we're going to spawn this process start, we're going to call start, which is going to spawn this process based on the server loop here. This is a really short piece of code here. We're going to fall into a receive block. We're going to wait for someone to send us a stop message. If we don't, after 200 milliseconds, we're going to say, nice, we've got some uptime here, and then we're going to tail call loop into ourself passing plus one. So that's our logic. So let me, L.S., make sure that that code is there. I'll say compile, blabber, just a, blabber, just to make sure that I've got a fresh, good one here. Okay, and I'm going to say, I'm going to store off a PID, equal blabber start. Okay, so I've got my process ID that was returned from that, and I'm here, and I'm saying, nice, zero years of bug free uptime on cat at deadless. Okay, I go over here, and it's like, I'd kind of like to do that too. So I'll say PID, equal blabber start, da, I don't know anything about that, because I'm not over here on bird, it wouldn't exist there either. But what I can do here is I can say nl, and I can say nl, blabber. And so what happened then is I just deployed my code to all my connected nodes. So over here on dog, I can now say PID, blabber start, and it works. And I can go back over here, and I can say, I want to spawn this process on another node. I want to say PID 2 is equal to node.spawn, and I'm going to spawn that on the bird node, and I'm going to spawn it by passing the node name, I'm going to pass in the module name, and I'm going to pass in the function name to call, and I'm going to pass in the arguments, which is an empty list, right? And so now this process is running over on bird, we've got the one running on here, but we're actually getting the IO piped to us. It's running over on this box. If we kill this thing, we would no longer be getting this message on the left saying six years of bug free uptime. Okay, so that's pretty cool, I think. So here, let's fix some code. We've got a bug in here, don't we? What's our bug here? We don't have enough gusto. It's our problem. Our bug here on this line is we need more gusto, we need an exclamation point here. Okay, so let's go over here, we fixed our bug, we're going to ship this code, and so we're going to first recompile it, and so we get this. Our next telcall into this, our bug is hotcode deployed on our running server, and I say nl to deploy this code to my other servers, and notice what's happening there. Over on our other cluster, over on another node, we have that picked up, and it deployed over here to this one as well, because its output is being piped back to us. So this is pretty crazy awesome, is what this is. And this is a short of example that I can show about, this is a basic way of showing how the foundations of how the real stuff works. So we've got to now hurry, because I took the luxury of a sweet, sweet demo. So let's talk just briefly about OTP. So this is where the safety and fault tolerance story really comes in, and it's built up on these basic things that we all get by using the Erlang VM, by using Elixir. We get applications, we get supervisors, and we get gen servers. Gen servers is where we do the work, and these all play with this nice system, and this is proven at Ericsson over the decades on these systems that have nine nines of uptime. So we're talking about milliseconds a year, and this is a common sort of thing. Everything has to be carrier grade for it to be telecom, which is five nines, but you actually beat that with Erlang because of these amazing bits here. So application supervisor gen server, this is sort of looking at the tree of it. So an application spins up and brings up all of the things that need to run in the context of that application. So you'll start up, you'll have supervision, where that supervision is then over here watching our gen server, right? And if that gen server hits some weirdness and dies, it'll restart. If this gen server down here causes some trouble, or any of its peers, we've got a bunch of gen servers being supervised by this supervisor, if any of those croak, this supervisor is going to restart them. If it happens so often, we meet some threshold, the supervisor here could actually be killed. And if that happens, this supervisor is going to bring that back up. And so you have these whole trees of these things depending on what you expect to happen in the code and how nasty you see the problems being. So in Elixir, we code the happy path. We don't have a bunch of try catchy stuff worrying about like, oh, what's going to happen? Because you never can really predict it. You can predict some things, but you should maybe just code it differently. But what's easier is to code the happy path, things go weird, just let it crash. Let the process crash and leave that problem of handling the error to supervision. On this side, different story. Unhandled exception means your application and by extension Node.js itself is an undefined state, blindly resuming means anything could happen. And this is right off of Node.js.org, and this terrifies me. The safe way to code for massive concurrency is to code sequentially. The easiest code in the world is code that goes top to bottom that you can just read. Instead of callbacks are not really easy to grok, so you actually code top to bottom in Elixir code. You have massive concurrency, but you're coding top to bottom. It's not your job to think about all of the plumbing of how the concurrency works. So think about this. You've got 100,000 connected users. They're making all these callbacks. You're running on the single threaded event loop on this single process, and you don't really have a supervision model. So one of those dies. So you've created this attractive nuisance here. Node is this attractive nuisance where people come in and they can just break their ass. You can really get hurt on this thing. We have all sorts of tools that we've been talking about so far in Elixir where you get out of this pit of failure, and you end up in a place where it's just actually easier to build systems at work. It's easier to do your day to day coding. One of those things is being able to code with a powerful REPL, the shell there. So when I'm building my Elixir code, I try it out in IEX. I can do all my things. I can see it work, and when it works, I hoist that up and put it into test to protect me against regressions. So this is like TDD, the part where you actually change your interface by the way you call it. You're getting that constantly inside of the REPL, and then you can then hoist that code out to protect you against regressions. So this idea of testing is big because it's big in the Ruby community. It's made very easy here in Elixir. Made easy by having good docs and then doc tests like we saw earlier. Website called the Node Way talks about, you know, this is protecting you from trouble kind of website. It's a guidance website. Node.js has always been easy to grasp, but difficult to master. They're common fitfalls. Never been well documented. It's up to you. There's a painful trial and error, you know, on and on and on, and it's like, oh my goodness. You know, this is the thing, this is the tool that's supposed to be easy. This is what was going to make us be able to write code more simply and deploy more simply, and it's just not what happens because we are required constant diligence there. And we shouldn't do this to ourselves. We shouldn't do that. We shouldn't allow tools and frameworks and languages to put us in that spot where we're constantly having to be on guard because we're fallible, we're human. So at this spot, we have now traveled through our hero's journey here where you've now had this introduction to this thing, and it's kind of up to you to go off and pick it up and do awesome things with it. And I think you're going to be stunned about what you can pull off and how it's not just easy at the beginning. It continues to be easy. It's easy as it can be, should be, I guess. And so hats off really for Jose over here for this thing he's built. It's absolutely stunning. And so at the end of this, I love this on the hero's journey, that they actually end with this line, it's return with the elixir. So hopefully you all will go and return with the elixir. My two closing bits here are elixir is pure sustainable joy is I think what you get on elixir and you get something maybe a little bit different over here. It's popular, it's crazy, and it's dangerous. And I'm going back to this country here at the end of the week, and so that's the world I live in. So thank you all for being here. We have this over here, so please vote and tweet and go off and install elixir and have fun with it. And then also come right back in here in a minute for our next session with Jan Quy. It's on F-Sharp in the real world, and so the FP track will be in this room all week other than the workshops, which is the hour after lunch. And for those, it will be in workshop, I think it's room 10, but it's workshops and it's where you can just hang out with all the speakers in the FP track and have them walk you through things. And so we'll have Jose, we'll have Joe Armstrong, we'll have Robert Verding, we'll have Matias Brandevinder who ran the F-Sharp machine learning workshop with Evelina. And so awesome bunch in there, I hope you join us for that. And other than that, actually I cannot believe it, I have a minute and a half for questions. Is anyone? Yes? Yeah, so you said I know about the variables. Which? I know it will basically just give for a particular problem. I think so, I think it has that sweet spot. I mean, it definitely has a sweet spot of standing up a website quickly that can handle lots and lots of things, but then, you know, it's like you've got to then have someone actually do the work. That's my question actually. When do you see like, using Node for an API or something, for instance, and seeing if you have 100,000 users, things can get herring, right? They would there. I mean, that would be easy. It's easy to handle 100,000 users on the early VM. This is a sweet spot of the language, that fault tolerance concurrency distribution, that's what it was built for. So back in the 80s, that was what it was built for. 100,000 phone connections coming in, and people expect their phone, they did expect their phone, before mobile phones, with apps. You expected your phone to work, and so you had fault tolerance. So I remember as a kid, when a squirrel would get into the transformer on the power lines and go, and the house, all the power would go out, we'd pick up our phone, and we'd call the power company. And that just tells you about that sort of fault tolerance story, and it's real there, and it's real because of these tools. And so again, that early VM is why that's happening. Like, over half of the world, all of the traffic for mobile is going through this. So massive concurrency. Easy to do. I mean, it's just the sweet spot of the language. A place where I would use Node for, I think maybe what you were getting at, a place where I would use Node is here, where I am using Node. This is Adam. I think JavaScript is a great language for the client. You know, JavaScript obviously works well in a browser. And it's a very good thing to have on the client. It's ubiquitous. It's out there. People know it. You know the problems with it. And you don't have 100,000 people that are getting hurt if my Adam crashes. And so that idea of Adam and Electron, there are talks here this week on Electron, I believe. And so it's a good thing to have it there. It's really nice, the tooling they built up. But I wouldn't want to use it on something where I had to count on fault tolerance. And I wouldn't want to have my company building up on it for business logic. And I know companies that have done that. They got lured in. Their business logic, everything. They ported from C-Sharp because of problems that they saw there. They didn't like what the experience there. They moved over to Node and now they're trapped. You know, they feel like they're in deep. They started bringing in microservices, which is basically the plea for help. So like when Node shops start talking about microservices, what they mean is like, we've screwed up. We're going to have this tiniest bit of code. And it's like, maybe this will get us out of this trouble we're in. Well you think about what functions are and processes with a message passing. That's microservices. That's how you want to handle that problem. And so any other questions? Yes? So functional language, everything is immutable. I suppose that's your functions. Yeah. You have constant commands. Well, this is a really interesting one. So you'll never, ever hear on the Erlang VM anyone talking about Monads. But you have something that, so what is the IOMonad for? So we know in Haskell, if we're right in Haskell, that we want to have all of our code be sane and we want to be able to reason about the world, right? But we still have to have side effects, right? If your code doesn't have, if it can't write to the monitor, if it can't write to the hard drive, it can't write to the network card, you're not actually going to get anything done. So you wrap that then inside of the IOMonad. Well on Elixir and Erlang, the equivalent of that would be port drivers. So all of my Elixir code, my Erlang code, it can only talk to other processes through message passing, right? Can't reach out to the operating system, can't poke through, do anything. It's all in that safe, safe world. So the way that the ugly, scary world is hooked in is through port drivers, those are written in C and they meet a certain interface that makes them look to the Erlang VM as if they are Erlang or Elixir. They look native on that side. But you've got the scary, scary world there and the only thing that they can touch the outside world is a port driver, which is a process which can be supervised. And so, and you don't go off writing port drivers all the time because there's the file system, there's the network card, there are these basic number of things that you want to talk to on the outside world and the way you do that is through port drivers. But I love that question and I forgot to actually mention it earlier, so thank you. Yes? Are there things that the VM or Elixir might not do with that? So I'm always surprised. People talk, well, Erlang is not a great language for doing machine learning, that sort of thing. Well, it turns out it actually is pretty good at machine learning and here's an example of, so you see the F sharp digit recognizer project. So the thing it's not good at, so I'll say that you can actually do this and I'd explore this path of using it for this, the thing it's not good at is it doesn't have a static type system. So there are going to be errors that you don't catch at compile time. This is a place where F sharp absolutely just beats the hell out of us over on Elixir because static type system you catch all these problems. It depends on the kind of code you're deploying and why you're deploying it. So if you're going to a mobile phone, for example, where you have to go through the Apple store for a week review and all this and you can't change your code and you can't get users to install the new one, you want to catch every problem you can at compile time. So that's why I really am excited, you know, like Xamarin, which I have my Xamarin shirt under here, you know, they have this F sharp support and there's also a talk on F sharp and mobile coming up a little bit later today. But that's a place where I would use F sharp for sure over, you know, you don't even have the option of using Elixir on a mobile phone. But I would use it for those places. Now on the server, it's actually a lot easier, you think about this, we did this hot code deployment, it's easier to deploy that new Elixir code to a server than it would be if you had a static type system with DLLs and all that. You know, that was just crazy easy. We changed the code, deployed across this cluster and everything worked. And so it comes down to what your deployment story is. So I think in the short run, like if an app has to work really, really well immediately and it's going to be really hard to update, you know, that's a static type system problem. If it's something, you know, this other side you have to have a system that runs and runs and runs for years with no downtime, the static type system protects you in that first hour. You get your maximum, it's kind of like term life insurance, that sort of thing, you know, there's different thresholds when in the most valuable. Static type systems are helping you the most right when you deploy in that first little bit of the life. Something like Elixir or Erlang, they're helping you if you need that thing to be running for years with no downtime. And I think I am now out of time. So Jan will be in here, so don't get too far away because Jan will talk about F-sharp in the real world and he is awesome. He's an amazing presenter. And thank you all for being here. This is awesome. Thank you.
 All right, perfect.  So awesome to have you here.  Thank you, thank you.  We're going to talk about what every Node.js developer needs to know about Elixir today.  There's me on Twitter.  I respond on Twitter, so hit me there.  I love carrying this conversation on out of here, and if you have any questions, always  follow up with me there.  There's no expiration date on that.  I want to start off.  This illustration appeared in the Guardian shortly after December 25, 1914, and this is  an illustration of the Christmas truce, where the German and British soldiers that were  a trench warfare, with this excuse of coming out and burying their dead, they got together  and they were civil to each other.  In the middle of this horror that was going on, they stepped out and they acknowledged  each other's humanity.  And in technology, tech, we often break off into camps, and we don't do that so well.  A lot of times we don't reach out.  And so for the Node folks here, I really appreciate you all coming to a functional programming  talk.  And for the functional program people, I'm really glad you're here to think about this  Node side of things.  At the point that we make problems visible, then you can do something about it.  You can improve the situation.  But until you make them visible, it doesn't really happen.  And so, thanks.  So this idea of civility, we might hate a technology.  There might be problems with a technology.  We might know that a technology is dangerous.  But you have to understand how people got there and have empathy for them in both directions.  So my path, this sort of long road, you can tell by my gray hair, that I began writing  software professionally back in 1994.  And so I was writing C and VB, so the old VB, not VB.net, but kicking it old school.  And then Pascal, VB script, J script, JavaScript, and then C sharp on.  And through that path, I ran into lots and lots of problems.  I created lots of problems, like we all do.  But I probably created more than my share of problems.  And through that, I might not have been the best developer, but I was awfully good at  seeing my mistakes and trying to learn from them and seeing what the pitfalls were that  led me there.  And through that, I worked to try to help other people avoid pitfalls.  And that empathy that I tried to use in this land of imperative code and OO code during  the 90s and the aughts, interestingly, it had this reputation for being able to see  these problems and help.  And that led me then to Norway in 2007.  So I was here, was brought over for a large architectural risk assessment project.  So here in Oslo, there was a company that had a huge code base.  They had 20 million lines of managed C++ and C sharp code.  They had these 12 architects.  And we worked on this risk assessment of how is the software going to destroy the company  project over the six week period.  And through that, all of the problems that I imagined would be in the code base, those  were there.  So you could almost get Robert Martin's book and just hand that book over before you even  went in and looked at the code because those problems are common across all imperative  and OO systems.  Those code smells are there.  And so that was expected, that side of it.  Amazing team, but you expected the problems.  One thing I didn't expect, though, is there was a system in that shop that had been up  and running for four years without a millisecond of downtime.  All the other applications, they were crashing maybe multiple times a day.  It was embarrassing.  It was causing trouble.  You had dependencies within the code that made it hard to upgrade.  You had the mingling of state data and behavior, like we're told to do by Martin Fowler.  We had that all through the code and that caused all these defects in the software that  made it was really hard to solve problems.  And we had event storms because you had concurrency involved in this.  Concurrency's hard to do if you have mutable state.  Problem, problem, problem.  But this system, four years without a millisecond of downtime, that was unusual.  And so I asked more and more about it.  And I actually learned it was even more remarkable.  There had been two years previously, there had been a major code upgrade, this compiled  language.  They compiled and they'd pushed new updates to this running cluster without a millisecond  of downtime then.  So I was like, what is the spooky magic?  And so I learned for the first time the word earlying.  I'd never heard of it.  I was off imperative OO guy.  And I was happy there, sort of happy.  I knew I had problems and I knew there were problems, but I was comfortable there.  And so I dug in and I started learning more about earlying and my code changed.  And I have built systems that people tell stories about now that they've seen these  good things.  I haven't done that before, before I ran into the earlying VM.  And so it changed my life.  And so I'd like to come back to Norway and return the favor.  So I'm very thankful for this city and for what it's done for me and all the defects  it's kept me out of.  So here we have the Hebrew's journey.  This is sort of the arc that all novels and movies and everything follow, this arc of  the hero's journey.  And so that was the beginning of my hero's journey.  And hopefully, this will be the beginning of your hero's journey as you go through and  you pick up some of this knowledge.  We'll go through this ordinary world and we'll progress.  So for the node folks here, I imagine you came to node for some of these reasons.  It's really a welcoming community.  You can come in without knowing much about programming at all and you're welcome to in.  And that's awesome.  And it's easy to get started in node.  And there's no doubt about that.  It's easy to get started.  And you can be working in Angular, Durandal, Aurelia, one of these frameworks.  And if you need to have a back end, you need to stand that back up in quickly, well, you  can do that in node.  It's very easy to kick that up.  Everyone sort of knows JavaScript.  No one really knows JavaScript.  Everyone sort of knows it.  Then people will also come because they've been hurt in other stacks.  There's problems with the tools being too heavy or not being able to have enough control  over things, just various problems.  And there is a concurrency story on node.  It's different than I think a lot of people think it is.  But there is a story there and people know that concurrency is important.  So that brings people.  And then there's good support in Visual Studio and on Azure.  I think of this sort of progression in node.  And I have lots of friends that went through node.  I started working in node when it was brand shiny new because I was interested in the  story of it.  I pretty quickly then dropped it because I had already learned Erling at that point.  And I saw it's like this isn't really filling the bargain that I thought it should be.  And so, but this is this progression.  We start off with folks that are junior.  And they're full of optimism.  You know, they haven't even heard the horror stories yet.  They haven't heard any of the bad.  It's just this welcoming community.  They come in and they're excited about this.  And that is a beautiful thing to have.  And at some point you move on and you then have your sort of engineers.  And they have heard the problems.  Maybe they've seen a few problems.  But the thing is, they can say, I'll be a craftsman.  I see these problems.  They're documented.  They don't know how to actually be diligent and not run into these problems myself.  And that's that tier.  This is the second stage of node development.  And then you move on to the seniors and the leads.  And I have friends that are in this spot right now.  They bought into this.  They brought their companies along.  And they've heard the problems.  They've seen the problems.  And now they're like, oh my God, what have I done?  You know, they've got themselves in a trap because they used it for everything.  They used it for things far, far outside of its sweet spot.  And they're in a terrible place.  And they're having trouble shipping code.  That's rough.  That's a rough spot to be in.  And those folks, I'm excited about where they're at.  I'm excited about all of these groups coming in because it's a great feeder into Elixir,  I believe.  But the folks that are senior, they're looking for escape pods.  And a lot of them are joining up at the Elixir user groups around the country, so around  the world.  So you'll have this mix of Ruby people.  And you'll have this mix of node people.  And then a few scattered FP people showing up at the Elixir meetups.  And so I'm really tickled about this linkage and this connection.  When on node, when people talk about node, they often use the word scalable.  And it's sort of a problem, I believe, to use the word scalable in the context of node.  Well, scalable is a rough word.  It's sort of a buzzword, marketing word.  It's a word that managers like to use even though they don't know what it means.  And I feel like you could say, okay, you've got a fast car.  Describing a car is a fast car.  You've got a car that goes and flies through the guardrails and falls down the bluff at  terminal velocity.  And you could say that that's a fast car, but you're missing an important part of the  story by calling that a fast car.  There's other things going on.  And so when you call node scalable, there's an issue in that it can handle the 20,000  connections that come in.  It can handle the 20,000 users as long as you immediately pass that off for something  else to do the work.  Because if you do the work, you then have got this issue of where you're blocking.  You're blocking your other 19,999 users.  So the issue then is like, okay, we hand off the work, or who's going to do the work then  and what do we write that in?  And there are also solutions.  Every time you run into a problem, there's a lot of ingenuity in the node community,  and they have solutions.  You'll have things like Q. And you'll have these ways of just passing things off these  libraries that have been written.  But it's always hard manual work and a lot of learning and discipline involved.  A lot of folks, you'll see a lot of blog posts that will say node is not a silver bullet.  And I think you could say that about most technologies.  It's not the thing that solves everything.  But there's another way of actually looking at the problem of silver bullet.  And in this sense, I think maybe node is a silver bullet.  In that a silver bullet has a really narrow use case.  And there's a sweet spot for a silver bullet, and that is to kill werewolves.  And day to day, there aren't nearly as many werewolves running around as Hollywood would  make you think.  And so the sweet spots that you'd fit, there aren't as many solutions where it does map  up closely.  And so a more, more of an uglier view of this might be it's maybe not the silver bullet,  maybe it's more like the full moon that brings out sort of some crazy in the environment.  And I'm kind of off of this part of the talk.  But I've seen so many of my friends hurt by this, and I believe that this is the most  dangerous technology in the world.  And so, and I hope that you take this in the spirit that I'm offering it, that I'm really  trying to help and I'm trying to keep problems from happening.  So let's now move on to Elixir and how it came to be.  So we've got this history of a character named Jose Valim who is here at the conference  this week to speak.  And so he was a core member of the Ruby on Rails team.  And he was trying to solve problems on Ruby.  All the, you know, he's a good developer.  He's focused on these issues.  It's hard to solve problems on Ruby.  Like, people would ask for scale.  They would ask for concurrency.  They'd ask for performance.  It's a hard thing to deliver on Ruby.  And so he was battling that battle.  And he was then reading seven languages in seven weeks.  Out of curiosity, who else heard this book?  Awesome, awesome.  Yeah.  And so he got to the chapter on Erlang and he was like, whoa, he was kind of like everyone  does when they first hear about what this thing does.  And they're like, that's weird.  Why haven't I heard of this thing?  And so he was reading about Erlang and he saw that it fit these problems of fault tolerance,  concurrency, distribution.  This scale thing that he had been asked to solve.  And so he started looking into Erlang then.  It's like, first, like everyone does when they first bump into Erlang, they think, okay,  can I steal parts from Erlang and bring it over into my stack?  And there are reasons you can't do that that we'll talk about briefly.  It's really hard.  It's a part, hard problem.  And so he's a smart guy.  He realized it pretty quickly.  You can't do this.  It's not going to happen.  So he thought, maybe I'll become an Erlang developer.  Okay.  Erlang is known for one thing and that's it's about developer joy.  Right?  It's a happy place to be a developer.  They hug each other.  You know?  It's like a good spot.  It's not necessarily known for those other things we're talking about.  But it is about developer joy.  Now you can see the reverse about Erlang.  So it is good about solving these hard engineering problems.  You've got these Krusty engineers that created the language.  Two of them are here this week.  So we have Joe Armstrong and Robert Verding, Krusty, Sirius engineer guys.  And so they weren't focused on the problem of DevJoy.  Ericsson and Stockholm, they weren't focused on that problem.  And so Jose decided, I'm going to take, I've got another approach.  Instead of trying to rip off Erlang, what I'm going to do is I'm going to write a new  language that targets the Erlang VM.  And that's the path he went down.  It's like, I'm going to build developer joy, good modern tooling, all this on top of this  VM that has this amazing track record.  And we're going to talk now about the sweet spots.  So Elixir, it's also approachable.  And it's productive not just in the short term, but in the long term.  So it's approachable, productive, and you have modern tooling.  So first about approachable, we can look at, you go to elixirlang.org and it's a useful  website.  It's not just a thing because you've got to have a website.  It's really useful of learning the language.  And so you jump in there and you go to the Getting Started guide, down on the right here,  you see 1 through 21.  And you actually have a really good handle of the language just by following those pages.  You can start here instead of getting a book and you'll do fine.  Then as you're going through that, you can also go to this other link here and find all  the meetups around the world.  And you'll see a bunch of Ruby people and a bunch of node people and functional programming  people scattered in.  This is the pattern I've seen city by city.  You can go to GitHub, see the code, see the language, and contribute.  And you'll have feedback from Jose right on the side.  So you have this, you get a pull request and he's sending hearts all over the place.  And so this is a nice thing to see this Ruby love showing up inside of this language.  He's a great guardian of the language.  He's a great protector and he's also very interested in bringing in ideas from all outside  places.  Another part of the tooling story is Hex.  You have Hex PM, it's a package management system.  So you can use this for your Erlang code, which you don't have because there aren't  any Erlang developers in the world.  There's like maybe five, ten, you know, there are a few of us.  And so there aren't many.  But this Elixir side, there are a lot.  And that's a growing thing.  And so we go off and we see some of the libraries out here.  You won't find libraries that do like three lines of code libraries.  These are libraries that take on more serious things that people need all the time.  But you won't have your six lines of code on a package.  And also if you go to something like Ecto and look at, you'll see that the level is  pretty good here.  This is the documentation off of a package that you pull down from Hex.  Hex is fast.  All sorts of good qualities about it.  Packages don't disappear on you on Hex.  It's just a mutable store of packages.  Packages disappearing on you.  This of course has been in the news this year.  Poor fellow over here, Aizer.  God bless him.  And so, you know, so he took a beating.  And there's a lot of beating that went around.  There's a lot of shydenfreude.  There's a lot of negative that happened here.  But I think it's comment by Tracy Harms is really nice.  This catastrophe isn't the fault of a single solitary developer's decisions.  And if a complete stranger can push some buttons and break your production deployment, you  have some thinking to do.  Especially if that was around six lines of code that was really about doing something  that the language should have done anyway out of the box.  Okay, modern tooling.  So we'll have this sort of retro, modern, hipster, bicycle thing here.  And so like all modern languages, we have the terminal is the way you do your good work.  And so we'll return to the terminal here.  IEX, the interactive Elixir shell.  When we say IEX, that brings up an Erlang node.  So it brings up an instance of the Erlang virtual machine and loads up all the Elixir goodies  here.  Okay, we go IEX and we are inside of IEX and we can do something like H, a noon.  So help.  We're going to get help on this thing.  We hit dot, we tab, and we get auto completion of all of the functions within the anew module.  Or within the anew, yeah, within the anew module.  And so we say, I'm interested in what count one does.  The count that takes one argument.  I'm interested in what that one does.  So we get this nice color.  We get examples right in the examples.  And this is the way you can go through all of the libraries in Elixir and you have this  help right at your fingertips.  Mix is another tool.  IEX is a tool, Mix is a tool.  Mix is ripped off from Clojure community.  There's a tool called Line again there.  You can see some of the commands we can do this.  You can think of it, build code, run your tests, scaffold new projects, and it's pluggable.  So additional things can come in.  So let's say Mix, new, Fizzbuzz.  We're going to scaffold out Fizzbuzz.  And here we go.  We get a readme markdown file, which is nice and modern.  We get a getignore built in, which ignores that we would want to have an Elixir project.  That's nice and modern.  And we are config.  And so when we have our Fizzbuzz module and then we have tests, I mean, this is nice.  We come in here and this is a nice place to be.  So let's go into CD into Fizzbuzz.  Say Mix test.  We compile and right out of the box we get one passing test.  So they already started off for us with a template for us to have tests.  So let's now go in and see what that story looks like.  Okay, so I have here our scaffolded out code off of our Fizzbuzz.  This is just what is...  So this is our one test that was scaffolded out for us and that's why we had our one.  Now I have a fully implemented Fizzbuzz over here.  And we can see it's down here.  We play to a number and it does a bunch of stuff that we don't have to worry about yet  because we're going to see about the syntax in a minute.  The thing I wanted to show here was the experience of saying Mix test.  Okay, so we have three tests and one failure.  So we saw one test a minute ago.  What's that about?  And why do we have a fail test?  Let's go in here and see what this fail test actually is.  So it says here Fizzbuzz play 10 to 16 and it expected a Fizzbuzz here but we had a  Fizz instead.  So let's go up here and see what that's about.  So what we have here is this is not a regular comment.  This is a doc test and so right in the middle of our comments we've included examples of  usage to make it easy for people to come in and right here this becomes part of our test  suite.  So we have Fizzbuzz play 1 to 5, it should get this and that became a unit test.  Fizzbuzz play 10 to 16 should get this and that became a unit test that actually failed  on us because we have a bug down here.  We have a pattern match that's too greedy and so what we need to do is move this code  up here, do this and then we need to move down here and we need to rerun our tests.  Oops, I forgot to save dinner.  Yeah, so our test passed now that was based off of that doc test.  So I think that's pretty sweet.  So another productive nice sweet part of Elixir is the Phoenix framework.  So this is a web framework that was built by the fellow who just walked in here, Jose  Neim, created the language and Sonny Skragan who is back there and Chris McCord and there's  a bunch of awesome people.  Chris was here last year, gave a talk, it's on Vimeo.  And so Phoenix is amazing but I'm not going to talk about it because there's a lot of  good content about it by people here later today.  But this is what a lot of people want when they come to a web framework.  So Elixir is functional.  And so we've probably heard a lot of buzz about functional over the last few years.  So a simple way of looking about functional is you have inputs that are transformed by  a function and you have then outputs.  A goes to B, inputs go to outputs.  You don't have, I'm going to come in, I'm going to set the table with all my state,  I'm going to set fields, properties, I'm going to have a class, all this stuff and  I'm going to call then functions that are going to mutate state and then I'm going  to lose track of what I just did a minute ago and I'm going to have all these bugs.  So instead you can look at the class, what came in as the input and know what should  have happened inside of the function and return.  This is important.  And this is a good way of getting out of a lot of those troubles that I saw when I was  my first trip to Norway.  Mutability is another part of functional programming and Elixir takes this very seriously.  It has to take this very seriously because the Erlang VM has a hard set of rules that  it enforces and this is one of them.  So it's not a thing you can turn off.  Separation of data and behavior.  So this is the thing we're talking about earlier about classes with their fields, their properties,  the data and their behavior mingle together which limits the use that you'd be able to  handle and use that class in.  This is in Elixir you have modules that have functions.  You don't have properties fields.  So you call into a module and you call a function within a module and it's just the inputs that  come in and then the outputs that go out.  So you spawn up a new process and you say this process I need to call into this function  passing in this input and I'm going to take the output of that and feed that into another  function and you just pipeline these things together and that's the way you build programs  inside of Elixir.  So we have expressive dev joy.  Let's talk a bit about the language now.  So language, language, language.  So we have IEX again and we're going to look at some of the types here.  So we have integer, expected, OX2A, that's kind of nice.  You know we get our hex right there.  We don't get barked at for having seven float divided by three.  It just does the thing you'd expect.  The thing.  You have a type called atoms that are sort of, they're the thing themselves.  They're only comparable to themselves.  They're just a handle or a constant that even if you have a whole cluster of different machines,  this like the atom goat is equal to the atom goat on the server and it's not equal to anything  other than the atom goat.  Strings are real strings inside of Elixir.  You might have heard stories, horror stories about Erlang where it's like, oh it's bad  at strings.  And it turns out it was a problem with naming, was the problem with Erlang and strings.  The thing they called a string is not what people expected it to be.  And in Elixir, a string is what you expect it to be.  You know you get this UTF-8 binary good thing and it behaves like you would expect it to.  Actually it behaves a little bit better than you'd expect it to.  And we'll see that in a second.  We have lists.  You have lots of list processing inside of functional languages and you have tuples.  So this is a positional thing.  So we see that.  Okay let's look at pattern matching for a second.  So x equals five.  So we got our five there.  And we'll say five equals x.  That's a little weird.  So what we're actually doing here, this is a pattern match.  And it's going to evaluate the same.  It's happy to say, yep five is equal to x.  This is a match.  And you can pin x down and say pin x equal five.  And it's happy to say that, you know that's it.  We say pin x is equal to x plus one.  It's going to bomb and say nope, no it's not.  Things not equal to six.  Left hand side is not equal to six.  We have then pattern matches that can be against more complex structures like tuples here.  So we have ABC tuple that matches against Apple Banana Cherry.  And we see that we then bound B to banana.  You know and then Apple and C, Apple to A and Cherry to C as well.  But that's what we showed here in the shell.  Pattern matching we'll have a little bit bigger of an example.  We have list here, one, two, three.  See it binds.  Does a pattern match sort of is a way of looking at it.  But we're actually assigning this thing.  So list is now equal to one, two, three.  And we say case our list and we're going to do pattern matching here inside of this case  statement.  So and we're doing this in the shell here.  You can have multi-line things.  You can have complex bits inside of the shell which is pretty awesome.  So we say case list do we say 11, 12, 13.  And this is not going to match because one, two, three is not going to match that right?  Okay is this going to match?  Nope, not going to match because this is a tuple.  One, two, three rather than a list.  One, two, three.  It's a different type, right?  Here we have one x three.  And this is going to match and it's going to bind the x that came in.  It's going to bind the two to the x in the middle and we can then use that later on in  the same case statement to do our string interpolation and show this.  And we'll see that happen here.  So matches and binds two to x.  Digit separators.  This is something that's coming in C sharp seven I believe.  So we've got a thousand.  I also can say a hundred.  I can score.  I can say, da, da, da.  So it's just pure candy.  I mean this is about the dev joy side of the language.  I mean there's just all these things that just make life a little bit nicer.  It's not important but it's just awesome though.  It's thoughtful.  So here we're going to look at enumson streams.  So we're going to define an anonymous function.  So a lot of times in functions if there's a convention of if it returns a true or false  you can put a question mark at the end of it.  So that's a nice convention.  You see it, you know what to expect.  So we're going to define this anonymous function that's going to use the rim function.  So rim returns the remainder of two numbers, you know, divided.  So this is like a module.  And so we say rim, the first argument, so the ampersand one is going to take that first  argument that's passed in.  It's going to rim that number, comma two, so we pass it in a five.  Remainder of five, comma two would be, well, one.  And so it's going to be an odd number, right?  So here we have a range.  We have one to a hundred thousand.  And we're going to pipe this forward.  So any F sharp people in the room?  All right, you'll recognize this.  So we've got one to a hundred thousand piping forward into so that each one of those values  are going to get pushed in as the first argument to the thing on the right.  So this functional pipelining.  A new map, and we're going to take whatever the argument was, we're going to multiply  it times three, and we're going to pipe that forward into a new filter.  And we're going to filter on our odd function that we defined at the top.  And then we're going to enum sum that.  And we get our answer.  Let's do the same thing, but this time we're going to use stream.map.  Stream.filter.  And then we do enum sum.  So the difference here, we get the same result.  The difference is, is stream is lazy.  And so on our first and our enum, each stage of that, we went through the whole computation  and we passed then that on to the next series in the pipeline.  With stream, it's dragging one at a time as you're coming through.  It's a pull-based thing.  And these both work off the same interface.  It's called a protocol that they both implement the enumerable protocol.  This is like interfaces in C sharp, or the protocol comes from closure, where this idea  is directly borrowed.  I mentioned strings earlier.  This is kind of cool.  We can have straight up UTF awesomeness right here.  So all the Norwegians with funny characters in your names, you can appreciate this, right?  Person equal.  So let's look at maps.  So we got our person name, Brian, beardy false.  I'm only beardy in the winter.  Not beardy in the summer.  And so we can access it by key, like this.  Person name, you can access it by dot, like this.  Get the same thing.  We can build a new map based on an old map and just push in the properties or the keys  that we're going to change or we're going to override.  And so we have then same thing, Brian Hunter here.  Okay, let's look at structs.  Yes?  In that part, did you still reference the old object?  Yep.  Yeah, I could do person and it's still there.  It's just that we have a new, everything's a copy.  There's, you know, it's not mutating.  So good question.  Here this builds up on top of that idea, but gives us some extra goodies.  So we're going to define this module called person here.  We're going to put a def struct in here.  We say name, and we're going to give it a default of empty string, and we're going  to say beardy and it's going to default defaults.  And we then have this data structure that we can start using.  So I say a person.  I get my defaults.  I'm going to say Brian is equal to a person named Brian.  So we see person, beardy, false, named Brian.  I say person, name Brian, barty, false.  Boom.  There's no such thing as barty.  So we got protected by using the wrong key there.  There's no such thing as barty.  There's beardy.  So it blew and barked and kept us from getting in this all sort of trouble that you've probably  all experienced with JSON.  All right.  Versatile.  This is a really crazy thing.  So the language, you expect certain things out of languages.  Here we have something you would only expect to be able to do in C. So we have the bit  syntax and we're going to run through this really quickly.  We're going to grab OK BIN data and we're going to read this file.  So if we look back on this image, this is a five pixel wide black, red, green, blue,  white, and this is the data below.  So we're going to read this file, capture it.  We capture BIN data.  We capture the binary data there to the BIN data variable.  And we're going to set up a pattern match where we're going to catch on the left using  this DSL called the bit syntax.  We're going to catch on the left the data if it matches against BIN data here.  And so we'll see how that worked.  So here's our data again.  Our left two bytes has to be BM in a bitmap.  So you can just go through and just think about data, you know, binaries out there and you  can just implement using this DSL and be able to process like whatever your protocol is  that you're trying to implement or your format.  So that was a match.  We're going to throw away 64 bits.  We're going to capture 32 bit little Indian into a variable called offset to pixels.  Throw away, grab five, height one, size we're going to throw 16 bits away.  We're going to make sure that the next thing is a 24 here.  And then we're going to throw the rest of it away.  Now we're going to say that offset to pixels.  This told us where the actual pixel data begins.  And we're going to remember that and we're going to throw away that many pixels.  And we're going to capture the rest of it into a variable called pixels.  We do that.  So we saw our values that were here.  So we have this four comprehension where we're going to capture, we're going to shove pixels  in eight bits, eight bits, eight bits into blue, green, red.  And here we go.  We've got our data.  So that's one line, one screen worth of code inside of the shell and we've, you know, parsed  bitmap, which is kind of awesome.  So something borrowed, a lot of things borrowed.  One of the things borrowed is Erlang VM.  Erlang VM grew up out of Erxon doing awesome, serious hardcore telecom things that were  focused on fault tolerance.  So to have fault tolerance, you have to have concurrency.  If you don't, process dies, you're fully down.  You have to have distribution.  If you don't, box catches on fire, you're fully down.  So those things are important.  When you see the track record of, you know, in fact, your phone works and that over half  of the world's mobile traffic is going through Erlang, which is pretty incredible, the data  text voice.  More recent story is WhatsApp with their victories on the Erlang VM.  You know, so just amazing, amazing numbers here, a billion active users a month and so  on.  And another number that's important to the business is $19 billion that they were paid  by Facebook.  There's 10 engineers building this mighty code base.  We look at what the Erlang VM is in context.  We have the runtime, we have OTP, we have languages Erlang, Elixir, List Flavored Erlang.  There's a talk here this week on List Flavored Erlang by Robert Verding.  And so here's why people can't just grab the Erlang VM, like Erlang bits and pull it into  their language.  It comes down to this thing as an operating system.  And it took a lot of time to build it.  It's a serious operating system.  It's not a general purpose operating system like Linux or Windows.  It's a special purpose operating system about making a safe place for code to run.  250 plus years of development went into it.  You can see an example of it being an operating system on Erlang on Zen, the Zerg demo.  And this boots up what would take 300 seconds to boot up a Linux VM on EC2.  Here they boot up into an instance of bare metal Erlang running on the Zen hypervisor.  Boots up in milliseconds, brings up the Erlang VM, runs a web server, processes things,  kicks out your request, and you have this result in.3 seconds.  Pretty awesome.  So let's look at the job of an operating system, which Erlang VM is, process management, interrupts,  memory management file system, so on and so on.  And think about what our code does, our C sharp, our C, our JavaScript, has a job.  And that job is to eat as much core as it possibly can.  It's trying to do, it's only worried about itself.  It's not interested about the safety of the rest of everything running on the machine.  And so the operating system kind of has to hate you.  It has to hate your code.  It can't trust it.  And this is the place where it's really different on the Erlang VM is because the Erlang code  cannot do things to hurt the stability.  The Erlang code itself has to play by the rules that the Erlang VM set up for it.  Erlang VM doesn't have to support C and Java and Ruby and all these languages.  It supports languages that only are going to do things that the Erlang VM allows them  to.  So that trust is nice.  When you can cooperate, you can get a lot done.  When everyone's fighting against each other, you don't get a lot done.  And so this is a big part of that story.  So we got our Shaun of the Dead reference.  We'll get back to processes.  So processes is the way we win here.  So concurrency.  Concurrency is not the same thing as parallelism.  A lot of times those words get used interchangeably, but concurrency is about the structure, doing  lots of things at once, and parallelism is about the execution of lots of things at once.  This comes in on a story at Ericsson.  So when they built Erlang in 1986, they weren't targeting multi-core machines in Stockholm  then.  This wasn't a thing then.  And so they built concurrency, and they didn't build it so that it could go twice as fast.  They built concurrency so that they could code without getting twisted up into these  horrible nests of callbacky weirdness and into thread weirdness.  And they wanted to make the code simple to read and to write, because code that's simple  to read and write is less buggy.  And that helps your fault-tolerant story.  So they did this massive moonshot from 86, and then they turned on multi-core in 2006,  and code that had been written a decade before, it did then run twice as fast on two cores,  four times as fast on four cores.  And like 2010 or 11, there was a test where it had linear scaling up to 40 cores on properly  written Erlang code.  We get that same thing in Elixir, because it's the same VM, all compiles down to the  same beam.  So let's look at Elixir and the Erlang VM and the Actor model.  So every Actor gets some props.  So our Actors are processes.  So every process gets these props.  One is memory.  So each process is one kilobyte on a 32-bit machine.  It's two kilobytes on a 64-bit machine.  Inside of this memory here, we have a heap and a stack, and it's that process is only.  No one else can reach in and grab a reference to memory inside of that process.  It's isolated.  And it's also immutable, right, because it's functional.  And so garbage collector, easiest job in the world to be a garbage collector on the Erlang  VM, because no one's, only one person's looking at the memory.  You can't change it once it's set.  And so each of these processes, they get their own isolated, dedicated garbage collector.  So there's not going to be a big stop to WorldGC that happens.  Each one gets garbage collected independently, which is pretty amazing.  And that's done for low latency, and it's done for deterministic scheduling.  Our mailbox, this is the only way a process talks to the world.  So last four, Yorick.  So we talk to the world through our mailbox.  This is the only way a process can reach out.  And so we send a message out of our mailbox.  We address it to another process.  It makes it an NSM box when they go into a receive block.  Links and monitors is the thing that we build up on to create some fault tolerance goodies.  This is at this OS level, this Erlang VM level, where we get links and monitors, links, basically  like I'm going to link to Jose over here.  And if Jose dies, I'm going to die with him.  Okay?  Sunny back here, and there's a different sort of thing.  So I'm going to monitor to Sunny back here.  So Sunny dies, well, I don't really exactly want to die, but I'd like you to tell me about  it.  I actually care about him, but I don't want to die.  And so it's a different level of commitment there.  And so that's these two tools you have out of the box.  So process scheduling on the Erlang VM.  We have a CPU core.  We have a single scheduler that lives on that CPU core.  Get three processes up.  And each one of these processes is going to get 2,000 swipes at the core.  2,000, 2,000, 2,000.  There's nothing in the world they can do to eat more core than 2,000 swipes.  They can't block and hold up to show.  Everyone gets preemptive scheduling here.  So this is another way of visualizing it.  They each get this much, and they get thrown back into the rotation.  Same thing happens if there's multi-core.  If there's big multi-core.  Yeah, all happening.  So we also have the supervision bit off the links and monitors it's talking about.  We have a supervisor and a worker.  The worker, something happens.  The network card's down.  The hard drive failed, whatever.  We have some weirdness.  The supervisor can then restart the worker.  And this is important because what do you do when you call tech support about something,  the story is reboot it, right?  That's the first thing they walk you through, and it always works.  And you're like, oh, it worked again.  And so this model is built in to Erlang.  It works so well for tech support that they included it as part of the language.  So process running, the process running, and boom, he falls into a receipt block.  He's going to sit here forever and ever and ever blocking, waiting for a message to appear  in his mailbox.  No one's talking to him, so he's going to sit here.  Well, does that wreck the show?  Have we now blocked and wrecked the show?  Well, no, we haven't.  Because the Erlang VM schedules him out of the mix, and then we schedule then across  the other two remaining cores, back and forth.  And we don't bring this guy back into the mix until the postman, the Erlang VM, the  operating system, until he knows that that process actually has mail.  When it does, he's brought back into the fold part of the rotation.  This includes things like file I.O.  So any sort of I.O. that we have goes through message passing like this.  So even though I write file read earlier on that bitmap file, when I said file read,  I was talking to another process, and then I waited for that process to send me a message  back.  I didn't have to do this as a developer.  It's just part of file and the read function on there.  It's part of GenServer.  And so at the point I asked for that file, immediately when I asked for it, that process  over there doing the file reading, and I'm removed from the rotation until I have a message  in my inbox.  So non-blocking I.O. that you don't have to worry about, you can treat like sequential  code.  It's really done right here.  Core cores for schedulers, you got processes, and we have this game of balancing compaction  that happens.  And so busy scheduler, busy scheduler, I'm not so busy.  I'm going to take some work from this guy, move it over here, so if this scheduler can  get sleepy and the whole core can go to sleep.  And this will happen so that you get this compaction across your cores, and in a server  closet you'll have half your cores being able to go to sleep if they're running early,  which is pretty amazing for power savings.  This core, memory locality, things are building up here, he's getting hot, hot.  This one's got some work stealing to make it even even balanced.  So get this game where we play and we get massive concurrency, primitive multitasking,  soft drill time, low latency.  And the low latency is valued more than raw throughput, which is an unusual characteristic  for a language.  Scheduling, parallelization, and fault tolerance in Node, because you're pretty much left to  your own devices here.  I mean, things, you know, you're going to build your own operating system, every project,  or use something out there that someone else has had to do.  So on Node we have cooperative multitasking, and on Elixir we have preemptive multitasking.  So cooperative multitasking, it sounds good, right?  But what it means is you have to cooperate, and if you don't, you can wreck the entire  scheduling system.  On Elixir you cannot do that.  Single threaded event loop.  Single threaded event loop, cooperative multitasking, it's like they read my mind.  What we do when we're, you know, we get into this trouble with callbacks, and I know that  this is one that you've heard a lot about, and there are a thousand blog posts out there  saying there's no such thing as callback hell, it's a myth, and all this.  But a lot of people are talking about it, so it's some people experience it.  But there's discipline, you can follow all these paths, you can go down this route, and  you can solve your callback hell problem and have flat code by hoisting things around and  flattening things out, and you know, on and on and on, and all these patterns if you're  a diligent person.  There's a funny use of words in Node, but we'll talk about that in a second.  So Node.js does not automatically manage the number of workers for you, however, it's  your responsibility to manage the worker pool for your application needs.  So Node's easy, that doesn't sound easy.  Distribution tends to be very unbalanced due to operating system scheduler vagaries,  loads have been observed where over 70% of all connections ended up on just two processes  out of a total of eight.  Well, Node's supposed to be easy, that doesn't sound easy to me.  Okay, here let's talk about Elixir and simplified distribution, and I think I actually do have  time for this demo, which is really awesome and surprising.  Okay, so here we have just a simple loop called blabber, and I'm going to move over here and  then use, I've got three consoles, a terminal window set up, and I'm going to start up  an IEX, and I'm going to pass it S name cat with a cookie of taco.  Here I'm going to start up a IEX with the name of dog with a cookie of taco, and here  I'm going to do bird with a cookie of taco.  So I've got these three named virtual machines, these three nodes brought up here.  Okay, and if I say node list, I don't have any friends yet.  So I say node connect, and I'm the cat, so I want to connect to the bird, and it says  true.  So if I say node list again, I see this, the bird, he knows that something's happened  too, and he's like, uh-oh, the cat knows about me, so I'm going to say node, not connect,  and I'm going to bring the dog into the mix because the dog always saves the cat, or saves  the bird from the cat.  So here, and I go back over here, and do my node list, and I'm like, oh, so we all know  about each other at this point, so we have a full mesh between these nodes, and that's  all it took to do this.  This can happen across multiple boxes, across heterogeneous hardware, so 64-bit windows,  32-bit Linux, a Raspberry Pi on ARM architecture, and we can have code this cluster formed,  and we can deploy code across these.  So the code I'm interested in deploying here is this blabber server.  So we're going to spawn this process start, we're going to call start, which is going  to spawn this process based on the server loop here.  This is a really short piece of code here.  We're going to fall into a receive block.  We're going to wait for someone to send us a stop message.  If we don't, after 200 milliseconds, we're going to say, nice, we've got some uptime  here, and then we're going to tail call loop into ourself passing plus one.  So that's our logic.  So let me, L.S., make sure that that code is there.  I'll say compile, blabber, just a, blabber, just to make sure that I've got a fresh,  good one here.  Okay, and I'm going to say, I'm going to store off a PID, equal blabber start.  Okay, so I've got my process ID that was returned from that, and I'm here, and I'm saying, nice,  zero years of bug free uptime on cat at deadless.  Okay, I go over here, and it's like, I'd kind of like to do that too.  So I'll say PID, equal blabber start, da, I don't know anything about that, because  I'm not over here on bird, it wouldn't exist there either.  But what I can do here is I can say nl, and I can say nl, blabber.  And so what happened then is I just deployed my code to all my connected nodes.  So over here on dog, I can now say PID, blabber start, and it works.  And I can go back over here, and I can say, I want to spawn this process on another node.  I want to say PID 2 is equal to node.spawn, and I'm going to spawn that on the bird node,  and I'm going to spawn it by passing the node name, I'm going to pass in the module name,  and I'm going to pass in the function name to call, and I'm going to pass in the arguments,  which is an empty list, right?  And so now this process is running over on bird, we've got the one running on here, but  we're actually getting the IO piped to us.  It's running over on this box.  If we kill this thing, we would no longer be getting this message on the left saying  six years of bug free uptime.  Okay, so that's pretty cool, I think.  So here, let's fix some code.  We've got a bug in here, don't we?  What's our bug here?  We don't have enough gusto.  It's our problem.  Our bug here on this line is we need more gusto, we need an exclamation point here.  Okay, so let's go over here, we fixed our bug, we're going to ship this code, and so  we're going to first recompile it, and so we get this.  Our next telcall into this, our bug is hotcode deployed on our running server, and I say  nl to deploy this code to my other servers, and notice what's happening there.  Over on our other cluster, over on another node, we have that picked up, and it deployed  over here to this one as well, because its output is being piped back to us.  So this is pretty crazy awesome, is what this is.  And this is a short of example that I can show about, this is a basic way of showing  how the foundations of how the real stuff works.  So we've got to now hurry, because I took the luxury of a sweet, sweet demo.  So let's talk just briefly about OTP.  So this is where the safety and fault tolerance story really comes in, and it's built up on  these basic things that we all get by using the Erlang VM, by using Elixir.  We get applications, we get supervisors, and we get gen servers.  Gen servers is where we do the work, and these all play with this nice system, and this is  proven at Ericsson over the decades on these systems that have nine nines of uptime.  So we're talking about milliseconds a year, and this is a common sort of thing.  Everything has to be carrier grade for it to be telecom, which is five nines, but you  actually beat that with Erlang because of these amazing bits here.  So application supervisor gen server, this is sort of looking at the tree of it.  So an application spins up and brings up all of the things that need to run in the context  of that application.  So you'll start up, you'll have supervision, where that supervision is then over here watching  our gen server, right?  And if that gen server hits some weirdness and dies, it'll restart.  If this gen server down here causes some trouble, or any of its peers, we've got a bunch of  gen servers being supervised by this supervisor, if any of those croak, this supervisor is  going to restart them.  If it happens so often, we meet some threshold, the supervisor here could actually be killed.  And if that happens, this supervisor is going to bring that back up.  And so you have these whole trees of these things depending on what you expect to happen  in the code and how nasty you see the problems being.  So in Elixir, we code the happy path.  We don't have a bunch of try catchy stuff worrying about like, oh, what's going to happen?  Because you never can really predict it.  You can predict some things, but you should maybe just code it differently.  But what's easier is to code the happy path, things go weird, just let it crash.  Let the process crash and leave that problem of handling the error to supervision.  On this side, different story.  Unhandled exception means your application and by extension Node.js itself is an undefined  state, blindly resuming means anything could happen.  And this is right off of Node.js.org, and this terrifies me.  The safe way to code for massive concurrency is to code sequentially.  The easiest code in the world is code that goes top to bottom that you can just read.  Instead of callbacks are not really easy to grok, so you actually code top to bottom in  Elixir code.  You have massive concurrency, but you're coding top to bottom.  It's not your job to think about all of the plumbing of how the concurrency works.  So think about this.  You've got 100,000 connected users.  They're making all these callbacks.  You're running on the single threaded event loop on this single process, and you don't  really have a supervision model.  So one of those dies.  So you've created this attractive nuisance here.  Node is this attractive nuisance where people come in and they can just break their ass.  You can really get hurt on this thing.  We have all sorts of tools that we've been talking about so far in Elixir where you get  out of this pit of failure, and you end up in a place where it's just actually easier  to build systems at work.  It's easier to do your day to day coding.  One of those things is being able to code with a powerful REPL, the shell there.  So when I'm building my Elixir code, I try it out in IEX.  I can do all my things.  I can see it work, and when it works, I hoist that up and put it into test to protect me  against regressions.  So this is like TDD, the part where you actually change your interface by the way you call  it.  You're getting that constantly inside of the REPL, and then you can then hoist that code  out to protect you against regressions.  So this idea of testing is big because it's big in the Ruby community.  It's made very easy here in Elixir.  Made easy by having good docs and then doc tests like we saw earlier.  Website called the Node Way talks about, you know, this is protecting you from trouble  kind of website.  It's a guidance website.  Node.js has always been easy to grasp, but difficult to master.  They're common fitfalls.  Never been well documented.  It's up to you.  There's a painful trial and error, you know, on and on and on, and it's like, oh my goodness.  You know, this is the thing, this is the tool that's supposed to be easy.  This is what was going to make us be able to write code more simply and deploy more  simply, and it's just not what happens because we are required constant diligence there.  And we shouldn't do this to ourselves.  We shouldn't do that.  We shouldn't allow tools and frameworks and languages to put us in that spot where we're  constantly having to be on guard because we're fallible, we're human.  So at this spot, we have now traveled through our hero's journey here where you've now  had this introduction to this thing, and it's kind of up to you to go off and pick it up  and do awesome things with it.  And I think you're going to be stunned about what you can pull off and how it's not just  easy at the beginning.  It continues to be easy.  It's easy as it can be, should be, I guess.  And so hats off really for Jose over here for this thing he's built.  It's absolutely stunning.  And so at the end of this, I love this on the hero's journey, that they actually end  with this line, it's return with the elixir.  So hopefully you all will go and return with the elixir.  My two closing bits here are elixir is pure sustainable joy is I think what you get on  elixir and you get something maybe a little bit different over here.  It's popular, it's crazy, and it's dangerous.  And I'm going back to this country here at the end of the week, and so that's the world  I live in.  So thank you all for being here.  We have this over here, so please vote and tweet and go off and install elixir and have  fun with it.  And then also come right back in here in a minute for our next session with Jan Quy.  It's on F-Sharp in the real world, and so the FP track will be in this room all week  other than the workshops, which is the hour after lunch.  And for those, it will be in workshop, I think it's room 10, but it's workshops and it's  where you can just hang out with all the speakers in the FP track and have them walk you through  things.  And so we'll have Jose, we'll have Joe Armstrong, we'll have Robert Verding, we'll have Matias  Brandevinder who ran the F-Sharp machine learning workshop with Evelina.  And so awesome bunch in there, I hope you join us for that.  And other than that, actually I cannot believe it, I have a minute and a half for questions.  Is anyone?  Yes?  Yeah, so you said I know about the variables.  Which?  I know it will basically just give for a particular problem.  I think so, I think it has that sweet spot.  I mean, it definitely has a sweet spot of standing up a website quickly that can handle lots  and lots of things, but then, you know, it's like you've got to then have someone actually  do the work.  That's my question actually.  When do you see like, using Node for an API or something, for instance, and seeing if  you have 100,000 users, things can get herring, right?  They would there.  I mean, that would be easy.  It's easy to handle 100,000 users on the early VM.  This is a sweet spot of the language, that fault tolerance concurrency distribution, that's  what it was built for.  So back in the 80s, that was what it was built for.  100,000 phone connections coming in, and people expect their phone, they did expect  their phone, before mobile phones, with apps.  You expected your phone to work, and so you had fault tolerance.  So I remember as a kid, when a squirrel would get into the transformer on the power lines  and go, and the house, all the power would go out, we'd pick up our phone, and we'd call  the power company.  And that just tells you about that sort of fault tolerance story, and it's real there,  and it's real because of these tools.  And so again, that early VM is why that's happening.  Like, over half of the world, all of the traffic for mobile is going through this.  So massive concurrency.  Easy to do.  I mean, it's just the sweet spot of the language.  A place where I would use Node for, I think maybe what you were getting at, a place where  I would use Node is here, where I am using Node.  This is Adam.  I think JavaScript is a great language for the client.  You know, JavaScript obviously works well in a browser.  And it's a very good thing to have on the client.  It's ubiquitous.  It's out there.  People know it.  You know the problems with it.  And you don't have 100,000 people that are getting hurt if my Adam crashes.  And so that idea of Adam and Electron, there are talks here this week on Electron, I believe.  And so it's a good thing to have it there.  It's really nice, the tooling they built up.  But I wouldn't want to use it on something where I had to count on fault tolerance.  And I wouldn't want to have my company building up on it for business logic.  And I know companies that have done that.  They got lured in.  Their business logic, everything.  They ported from C-Sharp because of problems that they saw there.  They didn't like what the experience there.  They moved over to Node and now they're trapped.  You know, they feel like they're in deep.  They started bringing in microservices, which is basically the plea for help.  So like when Node shops start talking about microservices, what they mean is like, we've  screwed up.  We're going to have this tiniest bit of code.  And it's like, maybe this will get us out of this trouble we're in.  Well you think about what functions are and processes with a message passing.  That's microservices.  That's how you want to handle that problem.  And so any other questions?  Yes?  So functional language, everything is immutable.  I suppose that's your functions.  Yeah.  You have constant commands.  Well, this is a really interesting one.  So you'll never, ever hear on the Erlang VM anyone talking about Monads.  But you have something that, so what is the IOMonad for?  So we know in Haskell, if we're right in Haskell, that we want to have all of our  code be sane and we want to be able to reason about the world, right?  But we still have to have side effects, right?  If your code doesn't have, if it can't write to the monitor, if it can't write to the hard  drive, it can't write to the network card, you're not actually going to get anything  done.  So you wrap that then inside of the IOMonad.  Well on Elixir and Erlang, the equivalent of that would be port drivers.  So all of my Elixir code, my Erlang code, it can only talk to other processes through  message passing, right?  Can't reach out to the operating system, can't poke through, do anything.  It's all in that safe, safe world.  So the way that the ugly, scary world is hooked in is through port drivers, those are written  in C and they meet a certain interface that makes them look to the Erlang VM as if they  are Erlang or Elixir.  They look native on that side.  But you've got the scary, scary world there and the only thing that they can touch the  outside world is a port driver, which is a process which can be supervised.  And so, and you don't go off writing port drivers all the time because there's the file system,  there's the network card, there are these basic number of things that you want to talk  to on the outside world and the way you do that is through port drivers.  But I love that question and I forgot to actually mention it earlier, so thank you.  Yes?  Are there things that the VM or Elixir might not do with that?  So I'm always surprised.  People talk, well, Erlang is not a great language for doing machine learning, that sort of thing.  Well, it turns out it actually is pretty good at machine learning and here's an example  of, so you see the F sharp digit recognizer project.  So the thing it's not good at, so I'll say that you can actually do this and I'd explore  this path of using it for this, the thing it's not good at is it doesn't have a static  type system.  So there are going to be errors that you don't catch at compile time.  This is a place where F sharp absolutely just beats the hell out of us over on Elixir because  static type system you catch all these problems.  It depends on the kind of code you're deploying and why you're deploying it.  So if you're going to a mobile phone, for example, where you have to go through the  Apple store for a week review and all this and you can't change your code and you can't  get users to install the new one, you want to catch every problem you can at compile  time.  So that's why I really am excited, you know, like Xamarin, which I have my Xamarin shirt  under here, you know, they have this F sharp support and there's also a talk on F sharp  and mobile coming up a little bit later today.  But that's a place where I would use F sharp for sure over, you know, you don't even have  the option of using Elixir on a mobile phone.  But I would use it for those places.  Now on the server, it's actually a lot easier, you think about this, we did this hot code  deployment, it's easier to deploy that new Elixir code to a server than it would be if  you had a static type system with DLLs and all that.  You know, that was just crazy easy.  We changed the code, deployed across this cluster and everything worked.  And so it comes down to what your deployment story is.  So I think in the short run, like if an app has to work really, really well immediately  and it's going to be really hard to update, you know, that's a static type system problem.  If it's something, you know, this other side you have to have a system that runs and runs  and runs for years with no downtime, the static type system protects you in that first hour.  You get your maximum, it's kind of like term life insurance, that sort of thing, you know,  there's different thresholds when in the most valuable.  Static type systems are helping you the most right when you deploy in that first little  bit of the life.  Something like Elixir or Erlang, they're helping you if you need that thing to be running  for years with no downtime.  And I think I am now out of time.  So Jan will be in here, so don't get too far away because Jan will talk about F-sharp in  the real world and he is awesome.  He's an amazing presenter.  And thank you all for being here.  This is awesome.  Thank you.
What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_0_71.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_72_155.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_156_659.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_660_803.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_804_2963.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_2964_4655.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_4656_15935.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_15936_16955.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_16956_17783.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_17784_17867.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_17868_21347.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_21348_22775.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_22776_23411.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_23412_23975.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_23976_24959.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_24960_25331.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_25332_25535.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_25536_26231.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_26232_26291.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_26292_26927.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_26928_27071.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_27072_27515.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_27516_29171.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_29172_29219.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_29220_29303.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_29304_30203.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_30204_32447.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_32448_32495.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_32496_33395.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_33396_33539.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_33540_35003.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_35004_36059.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_36060_36215.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_36216_38207.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_38208_44663.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_44664_44783.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_44784_44987.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_44988_45107.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_45108_46883.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_46884_47267.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_47268_47387.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_47388_47447.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_47448_47795.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_47796_47975.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_47976_48107.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_48108_48191.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_48192_48323.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_48324_48659.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_48660_49703.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_49704_50171.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_50172_50579.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_50580_50711.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_50712_50807.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_50808_51299.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_51300_54311.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_54312_54371.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_54372_54419.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_54420_55403.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_55404_55571.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_55572_59147.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_59148_68975.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_68976_69143.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_69144_69239.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_69240_69779.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_69780_69827.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_69828_69947.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_69948_70211.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_70212_70859.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_70860_70943.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_70944_71435.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_71436_71963.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_71964_73787.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_73788_75947.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_75948_76379.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_76380_77303.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_77304_77351.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_77352_77507.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_77508_77615.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_77616_77687.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_77688_81875.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_81876_82163.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_82164_84227.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_84228_84659.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_84660_85619.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_85620_85883.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_85884_86195.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_86196_89855.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_89856_95015.png What_every_Node_js_developer_needs_to_know_about_Bryan_Hunter_95016_98497.png
All right, perfect. So awesome to have you here. Thank you, thank you. We're going to talk about what every Node.js developer needs to know about Elixir today. There's me on Twitter. I respond on Twitter, so hit me there. I love carrying this conversation on out of here, and if you have any questions, always follow up with me there. There's no expiration date on that. I want to start off. This illustration appeared in the Guardian shortly after December 25, 1914, and this is an illustration of the Christmas truce, where the German and British soldiers that were a trench warfare, with this excuse of coming out and burying their dead, they got together and they were civil to each other. In the middle of this horror that was going on, they stepped out and they acknowledged each other's humanity. And in technology, tech, we often break off into camps, and we don't do that so well. A lot of times we don't reach out. And so for the Node folks here, I really appreciate you all coming to a functional programming talk. And for the functional program people, I'm really glad you're here to think about this Node side of things. At the point that we make problems visible, then you can do something about it. You can improve the situation. But until you make them visible, it doesn't really happen. And so, thanks. So this idea of civility, we might hate a technology. There might be problems with a technology. We might know that a technology is dangerous. But you have to understand how people got there and have empathy for them in both directions. So my path, this sort of long road, you can tell by my gray hair, that I began writing software professionally back in 1994. And so I was writing C and VB, so the old VB, not VB.net, but kicking it old school. And then Pascal, VB script, J script, JavaScript, and then C sharp on. And through that path, I ran into lots and lots of problems. I created lots of problems, like we all do. But I probably created more than my share of problems. And through that, I might not have been the best developer, but I was awfully good at seeing my mistakes and trying to learn from them and seeing what the pitfalls were that led me there. And through that, I worked to try to help other people avoid pitfalls. And that empathy that I tried to use in this land of imperative code and OO code during the 90s and the aughts, interestingly, it had this reputation for being able to see these problems and help. And that led me then to Norway in 2007. So I was here, was brought over for a large architectural risk assessment project. So here in Oslo, there was a company that had a huge code base. They had 20 million lines of managed C++ and C sharp code. They had these 12 architects. And we worked on this risk assessment of how is the software going to destroy the company project over the six week period. And through that, all of the problems that I imagined would be in the code base, those were there. So you could almost get Robert Martin's book and just hand that book over before you even went in and looked at the code because those problems are common across all imperative and OO systems. Those code smells are there. And so that was expected, that side of it. Amazing team, but you expected the problems. One thing I didn't expect, though, is there was a system in that shop that had been up and running for four years without a millisecond of downtime. All the other applications, they were crashing maybe multiple times a day. It was embarrassing. It was causing trouble. You had dependencies within the code that made it hard to upgrade. You had the mingling of state data and behavior, like we're told to do by Martin Fowler. We had that all through the code and that caused all these defects in the software that made it was really hard to solve problems. And we had event storms because you had concurrency involved in this. Concurrency's hard to do if you have mutable state. Problem, problem, problem. But this system, four years without a millisecond of downtime, that was unusual. And so I asked more and more about it. And I actually learned it was even more remarkable. There had been two years previously, there had been a major code upgrade, this compiled language. They compiled and they'd pushed new updates to this running cluster without a millisecond of downtime then. So I was like, what is the spooky magic? And so I learned for the first time the word earlying. I'd never heard of it. I was off imperative OO guy. And I was happy there, sort of happy. I knew I had problems and I knew there were problems, but I was comfortable there. And so I dug in and I started learning more about earlying and my code changed. And I have built systems that people tell stories about now that they've seen these good things. I haven't done that before, before I ran into the earlying VM. And so it changed my life. And so I'd like to come back to Norway and return the favor. So I'm very thankful for this city and for what it's done for me and all the defects it's kept me out of. So here we have the Hebrew's journey. This is sort of the arc that all novels and movies and everything follow, this arc of the hero's journey. And so that was the beginning of my hero's journey. And hopefully, this will be the beginning of your hero's journey as you go through and you pick up some of this knowledge. We'll go through this ordinary world and we'll progress. So for the node folks here, I imagine you came to node for some of these reasons. It's really a welcoming community. You can come in without knowing much about programming at all and you're welcome to in. And that's awesome. And it's easy to get started in node. And there's no doubt about that. It's easy to get started. And you can be working in Angular, Durandal, Aurelia, one of these frameworks. And if you need to have a back end, you need to stand that back up in quickly, well, you can do that in node. It's very easy to kick that up. Everyone sort of knows JavaScript. No one really knows JavaScript. Everyone sort of knows it. Then people will also come because they've been hurt in other stacks. There's problems with the tools being too heavy or not being able to have enough control over things, just various problems. And there is a concurrency story on node. It's different than I think a lot of people think it is. But there is a story there and people know that concurrency is important. So that brings people. And then there's good support in Visual Studio and on Azure. I think of this sort of progression in node. And I have lots of friends that went through node. I started working in node when it was brand shiny new because I was interested in the story of it. I pretty quickly then dropped it because I had already learned Erling at that point. And I saw it's like this isn't really filling the bargain that I thought it should be. And so, but this is this progression. We start off with folks that are junior. And they're full of optimism. You know, they haven't even heard the horror stories yet. They haven't heard any of the bad. It's just this welcoming community. They come in and they're excited about this. And that is a beautiful thing to have. And at some point you move on and you then have your sort of engineers. And they have heard the problems. Maybe they've seen a few problems. But the thing is, they can say, I'll be a craftsman. I see these problems. They're documented. They don't know how to actually be diligent and not run into these problems myself. And that's that tier. This is the second stage of node development. And then you move on to the seniors and the leads. And I have friends that are in this spot right now. They bought into this. They brought their companies along. And they've heard the problems. They've seen the problems. And now they're like, oh my God, what have I done? You know, they've got themselves in a trap because they used it for everything. They used it for things far, far outside of its sweet spot. And they're in a terrible place. And they're having trouble shipping code. That's rough. That's a rough spot to be in. And those folks, I'm excited about where they're at. I'm excited about all of these groups coming in because it's a great feeder into Elixir, I believe. But the folks that are senior, they're looking for escape pods. And a lot of them are joining up at the Elixir user groups around the country, so around the world. So you'll have this mix of Ruby people. And you'll have this mix of node people. And then a few scattered FP people showing up at the Elixir meetups. And so I'm really tickled about this linkage and this connection. When on node, when people talk about node, they often use the word scalable. And it's sort of a problem, I believe, to use the word scalable in the context of node. Well, scalable is a rough word. It's sort of a buzzword, marketing word. It's a word that managers like to use even though they don't know what it means. And I feel like you could say, okay, you've got a fast car. Describing a car is a fast car. You've got a car that goes and flies through the guardrails and falls down the bluff at terminal velocity. And you could say that that's a fast car, but you're missing an important part of the story by calling that a fast car. There's other things going on. And so when you call node scalable, there's an issue in that it can handle the 20,000 connections that come in. It can handle the 20,000 users as long as you immediately pass that off for something else to do the work. Because if you do the work, you then have got this issue of where you're blocking. You're blocking your other 19,999 users. So the issue then is like, okay, we hand off the work, or who's going to do the work then and what do we write that in? And there are also solutions. Every time you run into a problem, there's a lot of ingenuity in the node community, and they have solutions. You'll have things like Q. And you'll have these ways of just passing things off these libraries that have been written. But it's always hard manual work and a lot of learning and discipline involved. A lot of folks, you'll see a lot of blog posts that will say node is not a silver bullet. And I think you could say that about most technologies. It's not the thing that solves everything. But there's another way of actually looking at the problem of silver bullet. And in this sense, I think maybe node is a silver bullet. In that a silver bullet has a really narrow use case. And there's a sweet spot for a silver bullet, and that is to kill werewolves. And day to day, there aren't nearly as many werewolves running around as Hollywood would make you think. And so the sweet spots that you'd fit, there aren't as many solutions where it does map up closely. And so a more, more of an uglier view of this might be it's maybe not the silver bullet, maybe it's more like the full moon that brings out sort of some crazy in the environment. And I'm kind of off of this part of the talk. But I've seen so many of my friends hurt by this, and I believe that this is the most dangerous technology in the world. And so, and I hope that you take this in the spirit that I'm offering it, that I'm really trying to help and I'm trying to keep problems from happening. So let's now move on to Elixir and how it came to be. So we've got this history of a character named Jose Valim who is here at the conference this week to speak. And so he was a core member of the Ruby on Rails team. And he was trying to solve problems on Ruby. All the, you know, he's a good developer. He's focused on these issues. It's hard to solve problems on Ruby. Like, people would ask for scale. They would ask for concurrency. They'd ask for performance. It's a hard thing to deliver on Ruby. And so he was battling that battle. And he was then reading seven languages in seven weeks. Out of curiosity, who else heard this book? Awesome, awesome. Yeah. And so he got to the chapter on Erlang and he was like, whoa, he was kind of like everyone does when they first hear about what this thing does. And they're like, that's weird. Why haven't I heard of this thing? And so he was reading about Erlang and he saw that it fit these problems of fault tolerance, concurrency, distribution. This scale thing that he had been asked to solve. And so he started looking into Erlang then. It's like, first, like everyone does when they first bump into Erlang, they think, okay, can I steal parts from Erlang and bring it over into my stack? And there are reasons you can't do that that we'll talk about briefly. It's really hard. It's a part, hard problem. And so he's a smart guy. He realized it pretty quickly. You can't do this. It's not going to happen. So he thought, maybe I'll become an Erlang developer. Okay. Erlang is known for one thing and that's it's about developer joy. Right? It's a happy place to be a developer. They hug each other. You know? It's like a good spot. It's not necessarily known for those other things we're talking about. But it is about developer joy. Now you can see the reverse about Erlang. So it is good about solving these hard engineering problems. You've got these Krusty engineers that created the language. Two of them are here this week. So we have Joe Armstrong and Robert Verding, Krusty, Sirius engineer guys. And so they weren't focused on the problem of DevJoy. Ericsson and Stockholm, they weren't focused on that problem. And so Jose decided, I'm going to take, I've got another approach. Instead of trying to rip off Erlang, what I'm going to do is I'm going to write a new language that targets the Erlang VM. And that's the path he went down. It's like, I'm going to build developer joy, good modern tooling, all this on top of this VM that has this amazing track record. And we're going to talk now about the sweet spots. So Elixir, it's also approachable. And it's productive not just in the short term, but in the long term. So it's approachable, productive, and you have modern tooling. So first about approachable, we can look at, you go to elixirlang.org and it's a useful website. It's not just a thing because you've got to have a website. It's really useful of learning the language. And so you jump in there and you go to the Getting Started guide, down on the right here, you see 1 through 21. And you actually have a really good handle of the language just by following those pages. You can start here instead of getting a book and you'll do fine. Then as you're going through that, you can also go to this other link here and find all the meetups around the world. And you'll see a bunch of Ruby people and a bunch of node people and functional programming people scattered in. This is the pattern I've seen city by city. You can go to GitHub, see the code, see the language, and contribute. And you'll have feedback from Jose right on the side. So you have this, you get a pull request and he's sending hearts all over the place. And so this is a nice thing to see this Ruby love showing up inside of this language. He's a great guardian of the language. He's a great protector and he's also very interested in bringing in ideas from all outside places. Another part of the tooling story is Hex. You have Hex PM, it's a package management system. So you can use this for your Erlang code, which you don't have because there aren't any Erlang developers in the world. There's like maybe five, ten, you know, there are a few of us. And so there aren't many. But this Elixir side, there are a lot. And that's a growing thing. And so we go off and we see some of the libraries out here. You won't find libraries that do like three lines of code libraries. These are libraries that take on more serious things that people need all the time. But you won't have your six lines of code on a package. And also if you go to something like Ecto and look at, you'll see that the level is pretty good here. This is the documentation off of a package that you pull down from Hex. Hex is fast. All sorts of good qualities about it. Packages don't disappear on you on Hex. It's just a mutable store of packages. Packages disappearing on you. This of course has been in the news this year. Poor fellow over here, Aizer. God bless him. And so, you know, so he took a beating. And there's a lot of beating that went around. There's a lot of shydenfreude. There's a lot of negative that happened here. But I think it's comment by Tracy Harms is really nice. This catastrophe isn't the fault of a single solitary developer's decisions. And if a complete stranger can push some buttons and break your production deployment, you have some thinking to do. Especially if that was around six lines of code that was really about doing something that the language should have done anyway out of the box. Okay, modern tooling. So we'll have this sort of retro, modern, hipster, bicycle thing here. And so like all modern languages, we have the terminal is the way you do your good work. And so we'll return to the terminal here. IEX, the interactive Elixir shell. When we say IEX, that brings up an Erlang node. So it brings up an instance of the Erlang virtual machine and loads up all the Elixir goodies here. Okay, we go IEX and we are inside of IEX and we can do something like H, a noon. So help. We're going to get help on this thing. We hit dot, we tab, and we get auto completion of all of the functions within the anew module. Or within the anew, yeah, within the anew module. And so we say, I'm interested in what count one does. The count that takes one argument. I'm interested in what that one does. So we get this nice color. We get examples right in the examples. And this is the way you can go through all of the libraries in Elixir and you have this help right at your fingertips. Mix is another tool. IEX is a tool, Mix is a tool. Mix is ripped off from Clojure community. There's a tool called Line again there. You can see some of the commands we can do this. You can think of it, build code, run your tests, scaffold new projects, and it's pluggable. So additional things can come in. So let's say Mix, new, Fizzbuzz. We're going to scaffold out Fizzbuzz. And here we go. We get a readme markdown file, which is nice and modern. We get a getignore built in, which ignores that we would want to have an Elixir project. That's nice and modern. And we are config. And so when we have our Fizzbuzz module and then we have tests, I mean, this is nice. We come in here and this is a nice place to be. So let's go into CD into Fizzbuzz. Say Mix test. We compile and right out of the box we get one passing test. So they already started off for us with a template for us to have tests. So let's now go in and see what that story looks like. Okay, so I have here our scaffolded out code off of our Fizzbuzz. This is just what is... So this is our one test that was scaffolded out for us and that's why we had our one. Now I have a fully implemented Fizzbuzz over here. And we can see it's down here. We play to a number and it does a bunch of stuff that we don't have to worry about yet because we're going to see about the syntax in a minute. The thing I wanted to show here was the experience of saying Mix test. Okay, so we have three tests and one failure. So we saw one test a minute ago. What's that about? And why do we have a fail test? Let's go in here and see what this fail test actually is. So it says here Fizzbuzz play 10 to 16 and it expected a Fizzbuzz here but we had a Fizz instead. So let's go up here and see what that's about. So what we have here is this is not a regular comment. This is a doc test and so right in the middle of our comments we've included examples of usage to make it easy for people to come in and right here this becomes part of our test suite. So we have Fizzbuzz play 1 to 5, it should get this and that became a unit test. Fizzbuzz play 10 to 16 should get this and that became a unit test that actually failed on us because we have a bug down here. We have a pattern match that's too greedy and so what we need to do is move this code up here, do this and then we need to move down here and we need to rerun our tests. Oops, I forgot to save dinner. Yeah, so our test passed now that was based off of that doc test. So I think that's pretty sweet. So another productive nice sweet part of Elixir is the Phoenix framework. So this is a web framework that was built by the fellow who just walked in here, Jose Neim, created the language and Sonny Skragan who is back there and Chris McCord and there's a bunch of awesome people. Chris was here last year, gave a talk, it's on Vimeo. And so Phoenix is amazing but I'm not going to talk about it because there's a lot of good content about it by people here later today. But this is what a lot of people want when they come to a web framework. So Elixir is functional. And so we've probably heard a lot of buzz about functional over the last few years. So a simple way of looking about functional is you have inputs that are transformed by a function and you have then outputs. A goes to B, inputs go to outputs. You don't have, I'm going to come in, I'm going to set the table with all my state, I'm going to set fields, properties, I'm going to have a class, all this stuff and I'm going to call then functions that are going to mutate state and then I'm going to lose track of what I just did a minute ago and I'm going to have all these bugs. So instead you can look at the class, what came in as the input and know what should have happened inside of the function and return. This is important. And this is a good way of getting out of a lot of those troubles that I saw when I was my first trip to Norway. Mutability is another part of functional programming and Elixir takes this very seriously. It has to take this very seriously because the Erlang VM has a hard set of rules that it enforces and this is one of them. So it's not a thing you can turn off. Separation of data and behavior. So this is the thing we're talking about earlier about classes with their fields, their properties, the data and their behavior mingle together which limits the use that you'd be able to handle and use that class in. This is in Elixir you have modules that have functions. You don't have properties fields. So you call into a module and you call a function within a module and it's just the inputs that come in and then the outputs that go out. So you spawn up a new process and you say this process I need to call into this function passing in this input and I'm going to take the output of that and feed that into another function and you just pipeline these things together and that's the way you build programs inside of Elixir. So we have expressive dev joy. Let's talk a bit about the language now. So language, language, language. So we have IEX again and we're going to look at some of the types here. So we have integer, expected, OX2A, that's kind of nice. You know we get our hex right there. We don't get barked at for having seven float divided by three. It just does the thing you'd expect. The thing. You have a type called atoms that are sort of, they're the thing themselves. They're only comparable to themselves. They're just a handle or a constant that even if you have a whole cluster of different machines, this like the atom goat is equal to the atom goat on the server and it's not equal to anything other than the atom goat. Strings are real strings inside of Elixir. You might have heard stories, horror stories about Erlang where it's like, oh it's bad at strings. And it turns out it was a problem with naming, was the problem with Erlang and strings. The thing they called a string is not what people expected it to be. And in Elixir, a string is what you expect it to be. You know you get this UTF-8 binary good thing and it behaves like you would expect it to. Actually it behaves a little bit better than you'd expect it to. And we'll see that in a second. We have lists. You have lots of list processing inside of functional languages and you have tuples. So this is a positional thing. So we see that. Okay let's look at pattern matching for a second. So x equals five. So we got our five there. And we'll say five equals x. That's a little weird. So what we're actually doing here, this is a pattern match. And it's going to evaluate the same. It's happy to say, yep five is equal to x. This is a match. And you can pin x down and say pin x equal five. And it's happy to say that, you know that's it. We say pin x is equal to x plus one. It's going to bomb and say nope, no it's not. Things not equal to six. Left hand side is not equal to six. We have then pattern matches that can be against more complex structures like tuples here. So we have ABC tuple that matches against Apple Banana Cherry. And we see that we then bound B to banana. You know and then Apple and C, Apple to A and Cherry to C as well. But that's what we showed here in the shell. Pattern matching we'll have a little bit bigger of an example. We have list here, one, two, three. See it binds. Does a pattern match sort of is a way of looking at it. But we're actually assigning this thing. So list is now equal to one, two, three. And we say case our list and we're going to do pattern matching here inside of this case statement. So and we're doing this in the shell here. You can have multi-line things. You can have complex bits inside of the shell which is pretty awesome. So we say case list do we say 11, 12, 13. And this is not going to match because one, two, three is not going to match that right? Okay is this going to match? Nope, not going to match because this is a tuple. One, two, three rather than a list. One, two, three. It's a different type, right? Here we have one x three. And this is going to match and it's going to bind the x that came in. It's going to bind the two to the x in the middle and we can then use that later on in the same case statement to do our string interpolation and show this. And we'll see that happen here. So matches and binds two to x. Digit separators. This is something that's coming in C sharp seven I believe. So we've got a thousand. I also can say a hundred. I can score. I can say, da, da, da. So it's just pure candy. I mean this is about the dev joy side of the language. I mean there's just all these things that just make life a little bit nicer. It's not important but it's just awesome though. It's thoughtful. So here we're going to look at enumson streams. So we're going to define an anonymous function. So a lot of times in functions if there's a convention of if it returns a true or false you can put a question mark at the end of it. So that's a nice convention. You see it, you know what to expect. So we're going to define this anonymous function that's going to use the rim function. So rim returns the remainder of two numbers, you know, divided. So this is like a module. And so we say rim, the first argument, so the ampersand one is going to take that first argument that's passed in. It's going to rim that number, comma two, so we pass it in a five. Remainder of five, comma two would be, well, one. And so it's going to be an odd number, right? So here we have a range. We have one to a hundred thousand. And we're going to pipe this forward. So any F sharp people in the room? All right, you'll recognize this. So we've got one to a hundred thousand piping forward into so that each one of those values are going to get pushed in as the first argument to the thing on the right. So this functional pipelining. A new map, and we're going to take whatever the argument was, we're going to multiply it times three, and we're going to pipe that forward into a new filter. And we're going to filter on our odd function that we defined at the top. And then we're going to enum sum that. And we get our answer. Let's do the same thing, but this time we're going to use stream.map. Stream.filter. And then we do enum sum. So the difference here, we get the same result. The difference is, is stream is lazy. And so on our first and our enum, each stage of that, we went through the whole computation and we passed then that on to the next series in the pipeline. With stream, it's dragging one at a time as you're coming through. It's a pull-based thing. And these both work off the same interface. It's called a protocol that they both implement the enumerable protocol. This is like interfaces in C sharp, or the protocol comes from closure, where this idea is directly borrowed. I mentioned strings earlier. This is kind of cool. We can have straight up UTF awesomeness right here. So all the Norwegians with funny characters in your names, you can appreciate this, right? Person equal. So let's look at maps. So we got our person name, Brian, beardy false. I'm only beardy in the winter. Not beardy in the summer. And so we can access it by key, like this. Person name, you can access it by dot, like this. Get the same thing. We can build a new map based on an old map and just push in the properties or the keys that we're going to change or we're going to override. And so we have then same thing, Brian Hunter here. Okay, let's look at structs. Yes? In that part, did you still reference the old object? Yep. Yeah, I could do person and it's still there. It's just that we have a new, everything's a copy. There's, you know, it's not mutating. So good question. Here this builds up on top of that idea, but gives us some extra goodies. So we're going to define this module called person here. We're going to put a def struct in here. We say name, and we're going to give it a default of empty string, and we're going to say beardy and it's going to default defaults. And we then have this data structure that we can start using. So I say a person. I get my defaults. I'm going to say Brian is equal to a person named Brian. So we see person, beardy, false, named Brian. I say person, name Brian, barty, false. Boom. There's no such thing as barty. So we got protected by using the wrong key there. There's no such thing as barty. There's beardy. So it blew and barked and kept us from getting in this all sort of trouble that you've probably all experienced with JSON. All right. Versatile. This is a really crazy thing. So the language, you expect certain things out of languages. Here we have something you would only expect to be able to do in C. So we have the bit syntax and we're going to run through this really quickly. We're going to grab OK BIN data and we're going to read this file. So if we look back on this image, this is a five pixel wide black, red, green, blue, white, and this is the data below. So we're going to read this file, capture it. We capture BIN data. We capture the binary data there to the BIN data variable. And we're going to set up a pattern match where we're going to catch on the left using this DSL called the bit syntax. We're going to catch on the left the data if it matches against BIN data here. And so we'll see how that worked. So here's our data again. Our left two bytes has to be BM in a bitmap. So you can just go through and just think about data, you know, binaries out there and you can just implement using this DSL and be able to process like whatever your protocol is that you're trying to implement or your format. So that was a match. We're going to throw away 64 bits. We're going to capture 32 bit little Indian into a variable called offset to pixels. Throw away, grab five, height one, size we're going to throw 16 bits away. We're going to make sure that the next thing is a 24 here. And then we're going to throw the rest of it away. Now we're going to say that offset to pixels. This told us where the actual pixel data begins. And we're going to remember that and we're going to throw away that many pixels. And we're going to capture the rest of it into a variable called pixels. We do that. So we saw our values that were here. So we have this four comprehension where we're going to capture, we're going to shove pixels in eight bits, eight bits, eight bits into blue, green, red. And here we go. We've got our data. So that's one line, one screen worth of code inside of the shell and we've, you know, parsed bitmap, which is kind of awesome. So something borrowed, a lot of things borrowed. One of the things borrowed is Erlang VM. Erlang VM grew up out of Erxon doing awesome, serious hardcore telecom things that were focused on fault tolerance. So to have fault tolerance, you have to have concurrency. If you don't, process dies, you're fully down. You have to have distribution. If you don't, box catches on fire, you're fully down. So those things are important. When you see the track record of, you know, in fact, your phone works and that over half of the world's mobile traffic is going through Erlang, which is pretty incredible, the data text voice. More recent story is WhatsApp with their victories on the Erlang VM. You know, so just amazing, amazing numbers here, a billion active users a month and so on. And another number that's important to the business is $19 billion that they were paid by Facebook. There's 10 engineers building this mighty code base. We look at what the Erlang VM is in context. We have the runtime, we have OTP, we have languages Erlang, Elixir, List Flavored Erlang. There's a talk here this week on List Flavored Erlang by Robert Verding. And so here's why people can't just grab the Erlang VM, like Erlang bits and pull it into their language. It comes down to this thing as an operating system. And it took a lot of time to build it. It's a serious operating system. It's not a general purpose operating system like Linux or Windows. It's a special purpose operating system about making a safe place for code to run. 250 plus years of development went into it. You can see an example of it being an operating system on Erlang on Zen, the Zerg demo. And this boots up what would take 300 seconds to boot up a Linux VM on EC2. Here they boot up into an instance of bare metal Erlang running on the Zen hypervisor. Boots up in milliseconds, brings up the Erlang VM, runs a web server, processes things, kicks out your request, and you have this result in.3 seconds. Pretty awesome. So let's look at the job of an operating system, which Erlang VM is, process management, interrupts, memory management file system, so on and so on. And think about what our code does, our C sharp, our C, our JavaScript, has a job. And that job is to eat as much core as it possibly can. It's trying to do, it's only worried about itself. It's not interested about the safety of the rest of everything running on the machine. And so the operating system kind of has to hate you. It has to hate your code. It can't trust it. And this is the place where it's really different on the Erlang VM is because the Erlang code cannot do things to hurt the stability. The Erlang code itself has to play by the rules that the Erlang VM set up for it. Erlang VM doesn't have to support C and Java and Ruby and all these languages. It supports languages that only are going to do things that the Erlang VM allows them to. So that trust is nice. When you can cooperate, you can get a lot done. When everyone's fighting against each other, you don't get a lot done. And so this is a big part of that story. So we got our Shaun of the Dead reference. We'll get back to processes. So processes is the way we win here. So concurrency. Concurrency is not the same thing as parallelism. A lot of times those words get used interchangeably, but concurrency is about the structure, doing lots of things at once, and parallelism is about the execution of lots of things at once. This comes in on a story at Ericsson. So when they built Erlang in 1986, they weren't targeting multi-core machines in Stockholm then. This wasn't a thing then. And so they built concurrency, and they didn't build it so that it could go twice as fast. They built concurrency so that they could code without getting twisted up into these horrible nests of callbacky weirdness and into thread weirdness. And they wanted to make the code simple to read and to write, because code that's simple to read and write is less buggy. And that helps your fault-tolerant story. So they did this massive moonshot from 86, and then they turned on multi-core in 2006, and code that had been written a decade before, it did then run twice as fast on two cores, four times as fast on four cores. And like 2010 or 11, there was a test where it had linear scaling up to 40 cores on properly written Erlang code. We get that same thing in Elixir, because it's the same VM, all compiles down to the same beam. So let's look at Elixir and the Erlang VM and the Actor model. So every Actor gets some props. So our Actors are processes. So every process gets these props. One is memory. So each process is one kilobyte on a 32-bit machine. It's two kilobytes on a 64-bit machine. Inside of this memory here, we have a heap and a stack, and it's that process is only. No one else can reach in and grab a reference to memory inside of that process. It's isolated. And it's also immutable, right, because it's functional. And so garbage collector, easiest job in the world to be a garbage collector on the Erlang VM, because no one's, only one person's looking at the memory. You can't change it once it's set. And so each of these processes, they get their own isolated, dedicated garbage collector. So there's not going to be a big stop to WorldGC that happens. Each one gets garbage collected independently, which is pretty amazing. And that's done for low latency, and it's done for deterministic scheduling. Our mailbox, this is the only way a process talks to the world. So last four, Yorick. So we talk to the world through our mailbox. This is the only way a process can reach out. And so we send a message out of our mailbox. We address it to another process. It makes it an NSM box when they go into a receive block. Links and monitors is the thing that we build up on to create some fault tolerance goodies. This is at this OS level, this Erlang VM level, where we get links and monitors, links, basically like I'm going to link to Jose over here. And if Jose dies, I'm going to die with him. Okay? Sunny back here, and there's a different sort of thing. So I'm going to monitor to Sunny back here. So Sunny dies, well, I don't really exactly want to die, but I'd like you to tell me about it. I actually care about him, but I don't want to die. And so it's a different level of commitment there. And so that's these two tools you have out of the box. So process scheduling on the Erlang VM. We have a CPU core. We have a single scheduler that lives on that CPU core. Get three processes up. And each one of these processes is going to get 2,000 swipes at the core. 2,000, 2,000, 2,000. There's nothing in the world they can do to eat more core than 2,000 swipes. They can't block and hold up to show. Everyone gets preemptive scheduling here. So this is another way of visualizing it. They each get this much, and they get thrown back into the rotation. Same thing happens if there's multi-core. If there's big multi-core. Yeah, all happening. So we also have the supervision bit off the links and monitors it's talking about. We have a supervisor and a worker. The worker, something happens. The network card's down. The hard drive failed, whatever. We have some weirdness. The supervisor can then restart the worker. And this is important because what do you do when you call tech support about something, the story is reboot it, right? That's the first thing they walk you through, and it always works. And you're like, oh, it worked again. And so this model is built in to Erlang. It works so well for tech support that they included it as part of the language. So process running, the process running, and boom, he falls into a receipt block. He's going to sit here forever and ever and ever blocking, waiting for a message to appear in his mailbox. No one's talking to him, so he's going to sit here. Well, does that wreck the show? Have we now blocked and wrecked the show? Well, no, we haven't. Because the Erlang VM schedules him out of the mix, and then we schedule then across the other two remaining cores, back and forth. And we don't bring this guy back into the mix until the postman, the Erlang VM, the operating system, until he knows that that process actually has mail. When it does, he's brought back into the fold part of the rotation. This includes things like file I.O. So any sort of I.O. that we have goes through message passing like this. So even though I write file read earlier on that bitmap file, when I said file read, I was talking to another process, and then I waited for that process to send me a message back. I didn't have to do this as a developer. It's just part of file and the read function on there. It's part of GenServer. And so at the point I asked for that file, immediately when I asked for it, that process over there doing the file reading, and I'm removed from the rotation until I have a message in my inbox. So non-blocking I.O. that you don't have to worry about, you can treat like sequential code. It's really done right here. Core cores for schedulers, you got processes, and we have this game of balancing compaction that happens. And so busy scheduler, busy scheduler, I'm not so busy. I'm going to take some work from this guy, move it over here, so if this scheduler can get sleepy and the whole core can go to sleep. And this will happen so that you get this compaction across your cores, and in a server closet you'll have half your cores being able to go to sleep if they're running early, which is pretty amazing for power savings. This core, memory locality, things are building up here, he's getting hot, hot. This one's got some work stealing to make it even even balanced. So get this game where we play and we get massive concurrency, primitive multitasking, soft drill time, low latency. And the low latency is valued more than raw throughput, which is an unusual characteristic for a language. Scheduling, parallelization, and fault tolerance in Node, because you're pretty much left to your own devices here. I mean, things, you know, you're going to build your own operating system, every project, or use something out there that someone else has had to do. So on Node we have cooperative multitasking, and on Elixir we have preemptive multitasking. So cooperative multitasking, it sounds good, right? But what it means is you have to cooperate, and if you don't, you can wreck the entire scheduling system. On Elixir you cannot do that. Single threaded event loop. Single threaded event loop, cooperative multitasking, it's like they read my mind. What we do when we're, you know, we get into this trouble with callbacks, and I know that this is one that you've heard a lot about, and there are a thousand blog posts out there saying there's no such thing as callback hell, it's a myth, and all this. But a lot of people are talking about it, so it's some people experience it. But there's discipline, you can follow all these paths, you can go down this route, and you can solve your callback hell problem and have flat code by hoisting things around and flattening things out, and you know, on and on and on, and all these patterns if you're a diligent person. There's a funny use of words in Node, but we'll talk about that in a second. So Node.js does not automatically manage the number of workers for you, however, it's your responsibility to manage the worker pool for your application needs. So Node's easy, that doesn't sound easy. Distribution tends to be very unbalanced due to operating system scheduler vagaries, loads have been observed where over 70% of all connections ended up on just two processes out of a total of eight. Well, Node's supposed to be easy, that doesn't sound easy to me. Okay, here let's talk about Elixir and simplified distribution, and I think I actually do have time for this demo, which is really awesome and surprising. Okay, so here we have just a simple loop called blabber, and I'm going to move over here and then use, I've got three consoles, a terminal window set up, and I'm going to start up an IEX, and I'm going to pass it S name cat with a cookie of taco. Here I'm going to start up a IEX with the name of dog with a cookie of taco, and here I'm going to do bird with a cookie of taco. So I've got these three named virtual machines, these three nodes brought up here. Okay, and if I say node list, I don't have any friends yet. So I say node connect, and I'm the cat, so I want to connect to the bird, and it says true. So if I say node list again, I see this, the bird, he knows that something's happened too, and he's like, uh-oh, the cat knows about me, so I'm going to say node, not connect, and I'm going to bring the dog into the mix because the dog always saves the cat, or saves the bird from the cat. So here, and I go back over here, and do my node list, and I'm like, oh, so we all know about each other at this point, so we have a full mesh between these nodes, and that's all it took to do this. This can happen across multiple boxes, across heterogeneous hardware, so 64-bit windows, 32-bit Linux, a Raspberry Pi on ARM architecture, and we can have code this cluster formed, and we can deploy code across these. So the code I'm interested in deploying here is this blabber server. So we're going to spawn this process start, we're going to call start, which is going to spawn this process based on the server loop here. This is a really short piece of code here. We're going to fall into a receive block. We're going to wait for someone to send us a stop message. If we don't, after 200 milliseconds, we're going to say, nice, we've got some uptime here, and then we're going to tail call loop into ourself passing plus one. So that's our logic. So let me, L.S., make sure that that code is there. I'll say compile, blabber, just a, blabber, just to make sure that I've got a fresh, good one here. Okay, and I'm going to say, I'm going to store off a PID, equal blabber start. Okay, so I've got my process ID that was returned from that, and I'm here, and I'm saying, nice, zero years of bug free uptime on cat at deadless. Okay, I go over here, and it's like, I'd kind of like to do that too. So I'll say PID, equal blabber start, da, I don't know anything about that, because I'm not over here on bird, it wouldn't exist there either. But what I can do here is I can say nl, and I can say nl, blabber. And so what happened then is I just deployed my code to all my connected nodes. So over here on dog, I can now say PID, blabber start, and it works. And I can go back over here, and I can say, I want to spawn this process on another node. I want to say PID 2 is equal to node.spawn, and I'm going to spawn that on the bird node, and I'm going to spawn it by passing the node name, I'm going to pass in the module name, and I'm going to pass in the function name to call, and I'm going to pass in the arguments, which is an empty list, right? And so now this process is running over on bird, we've got the one running on here, but we're actually getting the IO piped to us. It's running over on this box. If we kill this thing, we would no longer be getting this message on the left saying six years of bug free uptime. Okay, so that's pretty cool, I think. So here, let's fix some code. We've got a bug in here, don't we? What's our bug here? We don't have enough gusto. It's our problem. Our bug here on this line is we need more gusto, we need an exclamation point here. Okay, so let's go over here, we fixed our bug, we're going to ship this code, and so we're going to first recompile it, and so we get this. Our next telcall into this, our bug is hotcode deployed on our running server, and I say nl to deploy this code to my other servers, and notice what's happening there. Over on our other cluster, over on another node, we have that picked up, and it deployed over here to this one as well, because its output is being piped back to us. So this is pretty crazy awesome, is what this is. And this is a short of example that I can show about, this is a basic way of showing how the foundations of how the real stuff works. So we've got to now hurry, because I took the luxury of a sweet, sweet demo. So let's talk just briefly about OTP. So this is where the safety and fault tolerance story really comes in, and it's built up on these basic things that we all get by using the Erlang VM, by using Elixir. We get applications, we get supervisors, and we get gen servers. Gen servers is where we do the work, and these all play with this nice system, and this is proven at Ericsson over the decades on these systems that have nine nines of uptime. So we're talking about milliseconds a year, and this is a common sort of thing. Everything has to be carrier grade for it to be telecom, which is five nines, but you actually beat that with Erlang because of these amazing bits here. So application supervisor gen server, this is sort of looking at the tree of it. So an application spins up and brings up all of the things that need to run in the context of that application. So you'll start up, you'll have supervision, where that supervision is then over here watching our gen server, right? And if that gen server hits some weirdness and dies, it'll restart. If this gen server down here causes some trouble, or any of its peers, we've got a bunch of gen servers being supervised by this supervisor, if any of those croak, this supervisor is going to restart them. If it happens so often, we meet some threshold, the supervisor here could actually be killed. And if that happens, this supervisor is going to bring that back up. And so you have these whole trees of these things depending on what you expect to happen in the code and how nasty you see the problems being. So in Elixir, we code the happy path. We don't have a bunch of try catchy stuff worrying about like, oh, what's going to happen? Because you never can really predict it. You can predict some things, but you should maybe just code it differently. But what's easier is to code the happy path, things go weird, just let it crash. Let the process crash and leave that problem of handling the error to supervision. On this side, different story. Unhandled exception means your application and by extension Node.js itself is an undefined state, blindly resuming means anything could happen. And this is right off of Node.js.org, and this terrifies me. The safe way to code for massive concurrency is to code sequentially. The easiest code in the world is code that goes top to bottom that you can just read. Instead of callbacks are not really easy to grok, so you actually code top to bottom in Elixir code. You have massive concurrency, but you're coding top to bottom. It's not your job to think about all of the plumbing of how the concurrency works. So think about this. You've got 100,000 connected users. They're making all these callbacks. You're running on the single threaded event loop on this single process, and you don't really have a supervision model. So one of those dies. So you've created this attractive nuisance here. Node is this attractive nuisance where people come in and they can just break their ass. You can really get hurt on this thing. We have all sorts of tools that we've been talking about so far in Elixir where you get out of this pit of failure, and you end up in a place where it's just actually easier to build systems at work. It's easier to do your day to day coding. One of those things is being able to code with a powerful REPL, the shell there. So when I'm building my Elixir code, I try it out in IEX. I can do all my things. I can see it work, and when it works, I hoist that up and put it into test to protect me against regressions. So this is like TDD, the part where you actually change your interface by the way you call it. You're getting that constantly inside of the REPL, and then you can then hoist that code out to protect you against regressions. So this idea of testing is big because it's big in the Ruby community. It's made very easy here in Elixir. Made easy by having good docs and then doc tests like we saw earlier. Website called the Node Way talks about, you know, this is protecting you from trouble kind of website. It's a guidance website. Node.js has always been easy to grasp, but difficult to master. They're common fitfalls. Never been well documented. It's up to you. There's a painful trial and error, you know, on and on and on, and it's like, oh my goodness. You know, this is the thing, this is the tool that's supposed to be easy. This is what was going to make us be able to write code more simply and deploy more simply, and it's just not what happens because we are required constant diligence there. And we shouldn't do this to ourselves. We shouldn't do that. We shouldn't allow tools and frameworks and languages to put us in that spot where we're constantly having to be on guard because we're fallible, we're human. So at this spot, we have now traveled through our hero's journey here where you've now had this introduction to this thing, and it's kind of up to you to go off and pick it up and do awesome things with it. And I think you're going to be stunned about what you can pull off and how it's not just easy at the beginning. It continues to be easy. It's easy as it can be, should be, I guess. And so hats off really for Jose over here for this thing he's built. It's absolutely stunning. And so at the end of this, I love this on the hero's journey, that they actually end with this line, it's return with the elixir. So hopefully you all will go and return with the elixir. My two closing bits here are elixir is pure sustainable joy is I think what you get on elixir and you get something maybe a little bit different over here. It's popular, it's crazy, and it's dangerous. And I'm going back to this country here at the end of the week, and so that's the world I live in. So thank you all for being here. We have this over here, so please vote and tweet and go off and install elixir and have fun with it. And then also come right back in here in a minute for our next session with Jan Quy. It's on F-Sharp in the real world, and so the FP track will be in this room all week other than the workshops, which is the hour after lunch. And for those, it will be in workshop, I think it's room 10, but it's workshops and it's where you can just hang out with all the speakers in the FP track and have them walk you through things. And so we'll have Jose, we'll have Joe Armstrong, we'll have Robert Verding, we'll have Matias Brandevinder who ran the F-Sharp machine learning workshop with Evelina. And so awesome bunch in there, I hope you join us for that. And other than that, actually I cannot believe it, I have a minute and a half for questions. Is anyone? Yes? Yeah, so you said I know about the variables. Which? I know it will basically just give for a particular problem. I think so, I think it has that sweet spot. I mean, it definitely has a sweet spot of standing up a website quickly that can handle lots and lots of things, but then, you know, it's like you've got to then have someone actually do the work. That's my question actually. When do you see like, using Node for an API or something, for instance, and seeing if you have 100,000 users, things can get herring, right? They would there. I mean, that would be easy. It's easy to handle 100,000 users on the early VM. This is a sweet spot of the language, that fault tolerance concurrency distribution, that's what it was built for. So back in the 80s, that was what it was built for. 100,000 phone connections coming in, and people expect their phone, they did expect their phone, before mobile phones, with apps. You expected your phone to work, and so you had fault tolerance. So I remember as a kid, when a squirrel would get into the transformer on the power lines and go, and the house, all the power would go out, we'd pick up our phone, and we'd call the power company. And that just tells you about that sort of fault tolerance story, and it's real there, and it's real because of these tools. And so again, that early VM is why that's happening. Like, over half of the world, all of the traffic for mobile is going through this. So massive concurrency. Easy to do. I mean, it's just the sweet spot of the language. A place where I would use Node for, I think maybe what you were getting at, a place where I would use Node is here, where I am using Node. This is Adam. I think JavaScript is a great language for the client. You know, JavaScript obviously works well in a browser. And it's a very good thing to have on the client. It's ubiquitous. It's out there. People know it. You know the problems with it. And you don't have 100,000 people that are getting hurt if my Adam crashes. And so that idea of Adam and Electron, there are talks here this week on Electron, I believe. And so it's a good thing to have it there. It's really nice, the tooling they built up. But I wouldn't want to use it on something where I had to count on fault tolerance. And I wouldn't want to have my company building up on it for business logic. And I know companies that have done that. They got lured in. Their business logic, everything. They ported from C-Sharp because of problems that they saw there. They didn't like what the experience there. They moved over to Node and now they're trapped. You know, they feel like they're in deep. They started bringing in microservices, which is basically the plea for help. So like when Node shops start talking about microservices, what they mean is like, we've screwed up. We're going to have this tiniest bit of code. And it's like, maybe this will get us out of this trouble we're in. Well you think about what functions are and processes with a message passing. That's microservices. That's how you want to handle that problem. And so any other questions? Yes? So functional language, everything is immutable. I suppose that's your functions. Yeah. You have constant commands. Well, this is a really interesting one. So you'll never, ever hear on the Erlang VM anyone talking about Monads. But you have something that, so what is the IOMonad for? So we know in Haskell, if we're right in Haskell, that we want to have all of our code be sane and we want to be able to reason about the world, right? But we still have to have side effects, right? If your code doesn't have, if it can't write to the monitor, if it can't write to the hard drive, it can't write to the network card, you're not actually going to get anything done. So you wrap that then inside of the IOMonad. Well on Elixir and Erlang, the equivalent of that would be port drivers. So all of my Elixir code, my Erlang code, it can only talk to other processes through message passing, right? Can't reach out to the operating system, can't poke through, do anything. It's all in that safe, safe world. So the way that the ugly, scary world is hooked in is through port drivers, those are written in C and they meet a certain interface that makes them look to the Erlang VM as if they are Erlang or Elixir. They look native on that side. But you've got the scary, scary world there and the only thing that they can touch the outside world is a port driver, which is a process which can be supervised. And so, and you don't go off writing port drivers all the time because there's the file system, there's the network card, there are these basic number of things that you want to talk to on the outside world and the way you do that is through port drivers. But I love that question and I forgot to actually mention it earlier, so thank you. Yes? Are there things that the VM or Elixir might not do with that? So I'm always surprised. People talk, well, Erlang is not a great language for doing machine learning, that sort of thing. Well, it turns out it actually is pretty good at machine learning and here's an example of, so you see the F sharp digit recognizer project. So the thing it's not good at, so I'll say that you can actually do this and I'd explore this path of using it for this, the thing it's not good at is it doesn't have a static type system. So there are going to be errors that you don't catch at compile time. This is a place where F sharp absolutely just beats the hell out of us over on Elixir because static type system you catch all these problems. It depends on the kind of code you're deploying and why you're deploying it. So if you're going to a mobile phone, for example, where you have to go through the Apple store for a week review and all this and you can't change your code and you can't get users to install the new one, you want to catch every problem you can at compile time. So that's why I really am excited, you know, like Xamarin, which I have my Xamarin shirt under here, you know, they have this F sharp support and there's also a talk on F sharp and mobile coming up a little bit later today. But that's a place where I would use F sharp for sure over, you know, you don't even have the option of using Elixir on a mobile phone. But I would use it for those places. Now on the server, it's actually a lot easier, you think about this, we did this hot code deployment, it's easier to deploy that new Elixir code to a server than it would be if you had a static type system with DLLs and all that. You know, that was just crazy easy. We changed the code, deployed across this cluster and everything worked. And so it comes down to what your deployment story is. So I think in the short run, like if an app has to work really, really well immediately and it's going to be really hard to update, you know, that's a static type system problem. If it's something, you know, this other side you have to have a system that runs and runs and runs for years with no downtime, the static type system protects you in that first hour. You get your maximum, it's kind of like term life insurance, that sort of thing, you know, there's different thresholds when in the most valuable. Static type systems are helping you the most right when you deploy in that first little bit of the life. Something like Elixir or Erlang, they're helping you if you need that thing to be running for years with no downtime. And I think I am now out of time. So Jan will be in here, so don't get too far away because Jan will talk about F-sharp in the real world and he is awesome. He's an amazing presenter. And thank you all for being here. This is awesome. Thank you.
they think, okay, can I steal parts from Erlang It's like, I'm going to build developer joy, good modern tooling, all this on top of this VM that approachable, productive, and you have modern around the world. And you'll see a bunch of Ruby developers in the world. There's like maybe five, another part of functional programming and Elixir expressive dev joy. Let's talk a bit about the themselves. They're just a handle or a constant all the Norwegians with funny characters in your those things are important. When you see the more than raw throughput, which is an unusual about Elixir and simplified distribution, and I Everything has to be carrier grade for it to be safe way to code for massive concurrency is to in workshop, I think it's room 10, but it's standing up a website quickly that can handle Adam. I think JavaScript is a great language for when Node shops start talking about on the server, it's actually a lot easier, you think about this, we did this hot code