 to actually want to talk a little bit about what Erlang is. So does anyone here, has anyone here written Erlang before? Q, okay. So some of this is going to be, some of the topics we discussed should be pretty straightforward to you. For everyone else, it's probably going to feel like programming 101. When I was getting into Elixir, trying to think recursively in an functional language is really like difficult at first and I felt like really stupid. But once it clicks, it will kind of change the way you think about writing programs, coming from like an object-oriented background. And we can't talk about Elixir before talking about Erlang. So Erlang is a language that's been somewhat obscure, at least for me. I come from a, I have a computer science degree, but I never heard of Erlang or really touched it in college. But really they were kind of like this, they had this nugget of like innovation for like the last 20 years. And they've been largely ignored by the programming community at large, at least object-oriented programming community. And Erlang was developed by company Ericsson to build like telecom, telecommunication systems. And it was, it's really unique because in like 1986 when it was developed, they had like a few set of requirements that even languages today don't really follow. They needed to build something that was kind of distributed at its heart so you'd be able to run on like much of telecom switches distributively, something that was highly concurrent and something that was highly fault tolerant. And even a lot of languages today don't really hit the like trifecta of those three requirements, at least as their focus. You may say some languages are like fault tolerant because they're stable, but Erlang actually has, mechanisms built in to like restart if something crashes and they really focus on the fault tolerance. So if you make a phone call today, for example, there's about a 50% chance it's running through an Erlang system. So Erlang is like tried and true, it's out there, and just to prove it's fault tolerance, you've never had a phone company call you, it's like a joke. Your phone company never calls and says, hey tonight you can't make a phone call from 8 to 10pm because we're going down for scheduled maintenance. Like you've never heard of that. And we half of our web services that we use have like downtime and scheduled maintenance. So Erlang has mechanisms built in to do like hot code uploading so like literally like zero downtime deploys where you can upgrade code live in production and go from one state to the next. And you can run programs distributively that have like no extra fanfare about writing jumping through hoops to run things distributively. You write code against one machine, you can write it on 50, and it all just works. So let's get started with Elixir. Elixir is, if you're familiar with Clojure, how Clojure relates to Java, Elixir relates to Erlang. So Elixir compiles to the Erlang virtual machine byte code and you can write Elixir, call it from your Erlang code and we can call Erlang code from our Elixir code. So Elixir isn't trying to reinvent the wheel, it's trying to build on top of all the innovation that Erlang in the Erlang virtual machine has basically brought for the last 20 years. And the reason why I really love Elixir is it brings some pretty awesome features to the table like metaprogramming. Erlang doesn't really have any great mechanism for like macros or metaprogramming. And as Rubyists, I think all of us are here partially because we love metaprogramming. So Elixir focuses on that, it adds a polymorphic layer through protocols so we're not writing object-oriented code but we don't have to throw away polymorphism in Elixir. You're familiar with Clojure's protocols, that's what Elixir's protocols were inspired by and we'll touch on what protocols are this afternoon. And Elixir also gives us a focus on like ease of use. So a lot of us come from Rails, we're at a Rails conference and Rails is all about being easy to use, having really nice features and Erlang, I think, has a history of being a little bit difficult to get into because they were focusing on more grittier problems historically, so a lot of the ramp up is much more difficult. So Elixir has a focus on ramping up quickly and getting beginners started easily. So for us to get started, we need to touch a terminology and then we'll get into some code just so you know what I'm talking about. The term is used all over the place and when we say an Elixir term, it basically means an element of any data type in Elixir and you'll see that in documentation everywhere. Literal is just a value of a term. When you hear the term binary, it's basically going to be a string of bits and this comes from Erlang and when we think of binaries in Elixir, it almost always is used to store like a UTF-8 encoded string and we'll use a term erity which you may not be familiar with and that's the number of arguments a function accepts. So if you understand those four or five terms, we should be pretty good as far as discussing the rest of the concepts. One thing you might like is everything is an expression which after I got into Ruby, I had never been familiar with that but once I basically got onto everything as an expression, I got into a language that doesn't abide by this. I kind of feel like I'm not quite getting the power of it. So here's an if condition in Elixir. We can store it as a result variable and it works like you would just expect in Ruby. It has this do here which is about the only difference if you were to write this in Ruby. Some people take a look at Elixir and think it's just Ruby syntax on Erlang. Don't be fooled by that. It's like a small veneer that might look a little bit like Ruby and kernels semantically or entirely different. My biggest complaint going between Ruby and Elixir on a daily basis is I write due in my Ruby code or I leave due off in my Elixir code and it sucks. Other than that, it's pretty nice. Elixir is in a mutable language so we have to change the way we write programs. We can no longer write objects that hide and strike like mutable state. We have to write our programs in like a data transformation way and that's a very difficult thing to get started with initially and hopefully we can kind of talk about that today. It follows the actor model of concurrency if you're familiar with that. parentheses are optional just like Ruby so to call a function as long as it doesn't introduce ambiguity it's going to be very similar to what you would do in Ruby and it has spawned a ton of debates just like in Ruby already. People hate that parentheses are optional but I love that they're optional. Documentation is first class. It's one of my favorite things. You write your documentation in markdown so you literally document your methods or your functions in markdown and then we can have access to them with an IEX. It's like if you had IRB up and you could just type a function and get the formatted markdown of that documentation right in like a shell and it's amazing. We have coexistence with the Erlang ecosystem which is huge. Elixir isn't trying to reinvent everything but we can call like an elixir function here we can call io puts it's like a Ruby put statement to print the standard out but if you want to call Erlang we can call it just like if you were like to chain a method off of a symbol in Ruby so that colon io is referencing that means hey there's an Erlang module named io I'm going to call the fwrite function on it so there's a complete interoperability between Erlang and elixir and vice versa it's a little bit uglier syntax if you want to call elixir from Erlang you have to prefix it within elixir module but calling it from Erlang from elixir is super straight forward like I can call math.py from the Erlang math module and I get pi why would you call elixir from Erlang? if you so if I release a elixir library that does something awesome and an Erlang person wants to use it pretty much for the same reason you would call Erlang from elixir there's a library out there that does what you want and you can drop in your project and use it and before we hop into some the first section here I want to talk a little bit about why I think elixir is the future of my programming career as much as I love Ruby how many people do threading in the Rails apps by showing ins how many people do threading on MRI in the Rails apps that one person so the concurrency story in Ruby in Rails is really weak it can be done but it's kind of like a wild west and it doesn't work that well for example we do a lot of real time stuff when we build Rails applications at work and we're constantly having to shove stuff into a background job and pull the server for trying to hit a third party API because we can't keep a connection open in our Rails process because it's got to clog the tubes basically so the way we get concurrency in Rails if we have like a quad core system we run like four processes of our Rails app and that's the way we achieve concurrency in Ruby so as more and more cores get added to CPUs so there are like 50 core CPUs on the horizon, 100 core CPUs if 10 years from now we were celebrate Rails 20th birthday and we have 50 core CPUs that are the norm on my laptop and we're constantly standing up here saying well we just run 50 Rails processes to achieve concurrency so I think that's a problem and I think it's inherent to Ruby's architecture some people get by perfectly like that that's how we deploy all of our Rails apps and it works really well but it starts to fall down if you're trying to do anything highly concurrent and if you're trying to do something like parallelize some work coordinate them together to do some work together and that's because we cannot properly do concurrency in Ruby in the ways we want to do it so getting into Elixir concurrency is basically the heart of everything we do and it gets rid of threading because you can say well we'll just add really proper threading in Ruby or we'll use jRuby get proper threading that still isn't the best way to achieve concurrency because you have to deal with like mutexes and locks you have shared mutable state it's really difficult to reason about because there are a lot of things around so writing in a functional way with a mutable state lets us write programs that are safe and concurrence and it's really simple to reason about and we'll see how message passing works later and we use processes that aren't operating system processes but we can run like a million of them on our machines so I can spin up a million Elixir processes and you couldn't spin up a million threads on any operating system that I'm aware of and if anyone's familiar with like WhatsApp that's a dollar fame recently they're running there are an Erling app and they're running a million concurrent connections per server to give you an idea of the language that I have coming from Ruby where we have like Action Controller live in Rails but if you go over like 15 concurrent requests you destroy your database pool of connections and all these things give me pause and think about where we need to move as a Rails community to handle concurrency properly so who here is still working on getting set up so by show of hands who has Erling at least built and installed that's still working on getting set up so you're still building Erling you're good okay so I'm going to get started try to pair with someone if they're working next to you this is pretty basic starting out but hopefully by the time you get into some real code examples you'll be able to type it in and be good to go so Elixir has just a very small set of types we have integer floats, Adam when you hear Adam you should think symbol in Ruby it's almost synonymous with symbols we call them Adams in Elixir we have a tuple a tuple is something that holds stored contiguously in memory you can think of it almost like an array it's allocated contiguously in memory and tuple comes from something that stores like multiple items like quintuple multiple so it sounds a little odd but that's what tuple comes from a list is a link list and we went through a bit string before it's just a string of bits and a pit is a process ID you can almost think of them like threads but they're very lightweight and it's like Elixir's unit of concurrency we can run like a million of them and from these small set of types we pretty much do all of our programming there's some a few other layers that Elixir builds on top but we basically instead of writing objects that like hide state we write functions to mutate some data structures so it's basically like data in data out from a very small set of types and you end up constructing your programs around all of these types so Adams are pretty self-explanatory just like Ruby you open up IEX we can just say Adam it's an Adam there's some built-in functions to type check so I can say is Adam Adam and it's true just like Ruby and it's just like Ruby in if you have user providing input and you want to call two Adam on it you can fill up the Adam table there's only a set amount of Adams it's a massive number but it's just like in Ruby if you ever call two Sim on user providing input you're potentially at risk for memory overflow because Ruby doesn't garbage collect the symbol table the same thing applies to Elixir so be careful when trying to take user input as Adam or as a string and then cast as an Adam Is there like a Elixir where you control C there's all these options like what's going on like from there can you like clear the Adam table or something I'm not sure I don't know that there's a command to do it there might be you can pass runtime options when you run IEX the maximum number of Adams larger if for some reason you required it I've never run into it in a real-world use case where I filled up the table but same rules apply within Ruby just don't cast user input to an Adam unless you know what's going on saw that yeah that's actually awesome and then tuples are stored contiguously in memory we define them between brackets and tuples can hold any term so any type we can store as a tuple so I can put a string inside say one two three and that's a valid tuple they can hold anything we want to shove in them that's built into Elixir and you would use tuples when you have a fixed set of data so tuples don't really lend themselves well to be appended to so if you had something like a three-element tuple that you know is always three elements you use a tuple it's very efficient very fast because it's stored contiguously in memory and they're kind of like the most basic data structure in Elixir and Erling so you would use them as like return types especially once we get into pattern matching tuples are used all over the place they're kind of like passed around and used as a way to like decorate data we'll see that in a moment lists are link lists and lists basically are used everywhere to store any kind of collection and again they're very basic but we build up our programs around some very basic data structures so we can create a list one two three four it works and we use like a head-tail denotation if anyone's familiar with other functional languages they use this ht notation for like a head of a list and a tail of a list and this is the way that we basically perform like recursive iteration internally and here's our first little bit of pattern matching which is gives me language envy every time I go back to Ruby so I can say okay I have some head I use like that pipe character and say I have some tail of a list and I want to store that as for pattern matching against some list right so it's almost like destruction or assignment if you've ever heard of that term and if I check the variable head I see that it's one and this is highly highly optimized by the virtual machine and this is our first taste of pattern matching which we'll get into some advanced examples so the original virtual machine basically is like a pattern matching genius that lives to pattern match and pattern matching basically it takes a thing on the left hand side and tries to match it against the thing on the right and you can basically use any term any data type in elixir and pattern match on its values yep that's just something pipe something it's actually a good question I was worried people might think that when I said the ht yeah so we can cast any variable there and this goes beyond that so I can say okay the first element of my list I expected to be one second element should be two third is a variable and then the rest is going to be the tail of the list that's totally valid so third is now three rest is going to be the remainder of the list and this works for any data structure so this is just a list we could have a tuple on the left hand side and it would work once we get into maps and structs later it works even at a more higher level which is super nice and it will blow up if it can't do a match so let's add that's how it works let's say our first element is not one it's going to blow up it's really angry there's a match error and this is Erling you can read that in red match error is like a nemesis for a lot of people getting into Erling especially because their programs will just blow up and the error will be match error no sack trace so Elixir is trying to get much better error messaging handling than Erling but you see match error a lot of times because that's the fundamental way to be careful how I say this so we want to make our programs crash instead of from exceptions which we'll get into later so ideally if something doesn't match when we expect it to we literally want our programs to crash from a match error and that will be supervised by another process and restarted or we can handle it in some other way so we write our programs around pattern matching and if something doesn't match a pattern that we expect it blows up with a match error by design and we'll see how that works so we don't end up in Ruby where you begin, rescue from this error, rescue from this error we very rarely rescue from errors in Elixir because by design an error is an exceptional state and we have no idea why it happens so trying to rescue from it from the Erling and Elixir philosophy isn't the right thing to do and we'll see that this afternoon once we get into OTP there's some helper methods like HD will give you the head of the list TL will give you the tail you don't want to use the head tail pattern match example you can just call it directly with the HD and TL method and Elixir has a build in that allows to help us work with lists in any kind of collection so enum is a build in module in Elixir that handles a polymorphic concept of a collection so we can iterate over a list we can iterate over a map and some other build in data types and you can write a protocol so we get into this afternoon that you can pass enum and this is where the polymorphism comes in where I could write this afternoon we'll have like the concept of a tweet and we'll be able to iterate over its messages by defining a enum protocol for it and if you have IEX up I want you to play with the H helper function because it's awesome, I miss it in Ruby so H is a build in helper function where I can say you know what you know tab can fleet your friend too so I'm going to type enum, hit tab I get a bunch of options but if I want to know what enum at is I can just say H enum at and there's that formatted documentation because it was documented in markdown so elixir when it compiles it stores all the markdown documentation as metadata you can get access to that and it's nicely color coded so constantly I always say I do IRB driven development during my Rails apps so I use a lot of IEX driven development it works the same way because I can come in I can even get my own code documentation like this so if I wrote my own module and I documented it I can say H in function name and bam I have documentation for it formatted directly from markdown and then you get some nice examples for it so for me this is a huge huge feature and especially as you're learning just like get in and explore so if I say H, can I do HH it's something like meta oh my gosh, yeah HH works so pretty cool so use H as your friend and then enum at I'll give you some niceties so we're going to go through some recursive examples with lists later just to give you to get you thinking recursively and then you'll probably never have to do that ever again because you'll use the enum module to do some list operations instead of writing it in your own recursive style and a big type in Elixir is keyword lists and this is basically syntactic sugar over lists and they're almost synonymous with like a hash in Ruby but they're not hashes lists when it's compiled so it's not meant for like true constant lookup time like hashes are so it's for like small sets of keys and values but they're very cheap and very easy to use and Elixir internally when it compiles your source code in its abstract syntax tree it's using keyword lists to do some really neat things which we'll see later so keyword list is defined pretty similarly like a hash in Ruby so we define it between brackets because really it's just a list so I can say the types in Elixir store it some variable and say one atom it's called an atom so it's just the key value as you would expect and we'll say we have what are some other types? couple so there's our keyword list and then I can access them like a hash in Ruby give it a key there's our value because we know like Ruby and anything about what Elixir is doing with this internally I'll show you this is just syntactic sugar I can say okay keyword list internally is stored is just a list of two element tuples the first element is the key the second element is the value so I can say I have a list let's take a tuple is that equal to the keyword list oops missed the quote so you'll find yourself if you control C out twice it's going to quit IEX and then you lose your history so you can actually type IEX break you find yourself in this scenario oh there we go okay so literally the thing on the left hand side is equal to the thing on the right Elixir just provides us some syntactic sugar on top of lists to do a nice set of key value pairs and we saw before in that first example you might remember we had an if statement so I say if true I can give it a do in block I can say if true do it's true find out oh my gosh it's true so everything between the do in the end and elixir is just literally syntactic sugar for if is a macro which we'll get into later so if you're calling if first element is an expression and then the second element between a do and end elixir converts that to literally a keyword list as a second argument and you can leave off the list brackets if it's the last argument like ruby you can leave off the hash bracket or hash braces similar concept so this is synonymous with and so that works so everything in elixir is built up literally as like a do in block as a single key keyword list the key is do and the value is the block of code when we get into writing macros this becomes super handy because we can inspect that and get like the AST directly of the code that we want there's a keyword module that provides some niceties so I can ask like give me the keys of some keyword list that I have and it's going to spit out the keys so elixir has a small standard library but it provides you most of the built in blocks that you need to write most of your programs so it's not as extensive as in ruby especially we're all familiar with like active support which like you forget what's ruby and what's active support so you're not going to have quite the array.47 to get the 47th element or the array.3d but the standard library actually is quite nice so it's really well thought out and I don't think I mentioned before who's aware of who Jose Valim is hopefully most people he wrote elixir, I meant to plug him initially he's prolific in the rails community he was a part of rails core he wrote devise, he wrote simple form he wrote probably he had a hand in probably half of the gyms that you use on a daily basis so he put elixir together and he's made some really excellent choices and it shows in my opinion in the standard library and in the metaprogramming round elixir in pretty much all areas what's the magic of break? IEX and then pound break should get you out let me find out actually I always forget so now I'm in like a bad state where it thinks I'm continuing an expression I should be able to hit control C once I think I might be actually in this no, eh I actually think that's uh elixir's IEX is built on top of the Erling URL shell I'm pretty sure that's Erling because we like a little better error messages than eh but it's alright really? so you're saying so you're saying I did what oh I see you're saying basically history is not in place yet so if you put out of your shell it's really frustrating because I can Ruby all constantly you know hit quit relaunch a shell and I'll have my history and elixir we don't get that yet and that's built on part because there's some it's built on top of the Erling shell and there's some issues with trying to get history in place I know that there was some pinning poor requests but I'm not aware of why they why we haven't quite gotten there yet so you do a lot of copy pasting if you ever quit out of IEX variables are immutable but what a lot some people hate that do Erling is that we can rebind variables to a new value some people call this immutability but they would be wrong my opinion so if I define a variable named some instead of saying define variables the term that we use is we bind variables to a value so I can say some is 10 now I have bind a thing named some to the value 10 if you're coming from Erling you would never ever in this scope be able to rebind some to a new value it would blow up with a an error because Erling is like single assignment principle if you've heard of that but elixir we can say okay now some is 12 and some people would say ah this is immutable language you've just changed some's value elixir is terrible a lot of people on twitter that are coming from Erling have hated on this concept but all we've done here is elixir still buys by the single assignment principle but internally when this is compiled it's saying okay we're going to take the thing that was named some and we're just going to rebind it to a new value anyone that had a reference to some prior to this some would still be 10 so we didn't actually mutate that variable that makes any sense is everyone clear on that I think I can show that with the anonymous function I said I can create a anonymous function we can see for the first time we'll say some value I could actually work too but then at the moment we added it it would actually be the value would be stored there not the reference to the variable so I can say IO.puts so this is anonymous function we define it with fn-rocket and then we give an end and just like JavaScript and some other functional languages functions that close over variables so it's going to close over the sum that was 12 so now I have sum value as an anonymous function and if I want to I'm going to change sum again okay sum is now 100 so if I invoke that anonymous function we see sum was 12 so we haven't mutated sum when we say sum equals 100 we just rebound that to a new value so this trips some people up coming from early because they're so used to defining like if they ever come into a case where they want to change something you'll see like sum 1 sum 2 sum 3 encode a lot and this gets around that and we can see that we can invoke anonymous functions with the dot notation which seems a little bit odd and some people really don't like this but as you get further into this I actually really like this so anonymous functions are invoked with it's called like dot notation or the dot operator and the reason why we have this is because if we didn't have if we want to invoke it some people want this to be changed to this coming from like a JavaScript background a lot of functional languages this would ruin zero function arity in a lixter so if we ever wanted to call a function off of a module in lixter as we plug it into later that didn't have that didn't take any arguments we would have to include the braces here's one example self will give you the current process ID and that's a building off the kernel if we didn't have the dot notation on anonymous functions we would no longer call self we would have to call self like this which still works so the dot notation resolves that ambiguity on do we want to call a function or do we want to reference to self they were unclear on that because like self and like javascript for example if we had a function self would return us a reference to that function but in a lixter zero arity is actually just going to invoke it so for anonymous functions we use the dot operator to actually explicitly invoke that function otherwise we just have a reference to it and then pattern matching we saw a little bit before is actually doing variable binding so first rest equals Alice Bob Ted list first and rest are going to be bound to the head and the tail of the list so we're actually doing a variable binding within pattern matching as we saw earlier this was a rebinding example so functions in a list in a lixter are first class like you would expect in a functional language we can define them and pass them around just like any good functional language does see if this is worth actually going through yeah might as well do it so we can define an anonymous function named add again we use FN notation and the arguments are passed in so adds going to take first number and a second number all it's going to do is add them together return the result pretty easy and just like in Ruby everything is an expression again so there's no return there's actually Ruby has a return keyword elixir has no concept of return so the last thing evaluated is a thing returned so we don't return in elixir we just write expressions so I can say okay we have some subtract as well and that's going to subtract the numbers so if I wanted to like perform some calculation I could say okay I'm going to perform a calculation takes a first number a second number and then a function as a third argument to invoke just to show you that we can pass these things around so I like to you can hit enter and it will continue that expression so you don't have to like write it on one line so we can say okay we want to explicitly invoke that function you pass to me with the dot operator and we'll just pass in the first number and the second number and there's our perform calc function so then we can see that functions are first class by saying okay I want to perform a calculation say 5 and 6 and I want to pass that add function that I define above and it works so functions are first class anonymous functions are actually used a lot less as far as passing them around and defining them explicitly like this we use anonymous functions as part of like enum modules and performing mapping operations but most of our code is going to live in modules that we'll get into very shortly so you're not going to be using the dot notation quite as often as you would think so if you hate it it really isn't used all that often compared to calling functions on modules which do not use the dot notation and Elixir has a shorthand function syntax for some cases where like writing the fn arguments is a little bit verbose so for example I have an enum map operation so mapping over a set just like Ruby's array collector array map we can map over a list multiply the first or multiply each element by 2 and we see if we get the correct result so this ampersand syntax is basically synonymous with saying okay I have some number and I want to multiply it by 2 so these two top and bottom are synonymous so we use ampersand to like create a shorthand function syntax and then ampersand 1 is going to say okay the first argument to this function do something with it so this is nice and succinct for very very simple operations but I caution everyone do not litter your code with the shorthand function syntax unless it's a very trivial transformation because it's one of these things that I try to say always be have clarity over brevity so if you get into like ampersand 1, ampersand 2 and you're doing some transformation on that data someone reading through your code later or your own self reading through your code later is going to have no idea what's going on so it's nice to use if we're just doing a simple operation otherwise use the expanded syntax is the rule that I try to bide by and you'll often hear people call the ampersand and then a function capture operator I've heard it called so we can like capture functions so some people say well if I have a reference to an anonymous function that I have to invoke but on modules I don't use the dot operator so if I want to do like kernel if I say like 5 plus 2 really what that's doing is calling the off the kernels imported plus function so literally 5 or 5 plus 2 it's actually doing this internally if I want to capture kernel plus as an anonymous function I prefix it with an ampersand so if I want to say okay add is actually going to be a captured function off of this module I have to do this so capture it by name and also arity so all functions in Elixir and Erling are defined by their name plus their arity so I have to give it slash 2 here and now I have captured Erling's and Elixir's plus operator and I had to specify the arity because there are no all of your functions cannot have like any arbitrary number of arguments and from Ruby especially from Rails half a time you can pass in a list half a time you can pass in like a splat you kind of have to ditch that idea coming into Elixir because we are fixed by name plus arity but what we lose in being able to pass like splat arguments we gain in using pattern matching and writing our code around pattern matching and we'll see once we define modules how well that works out so you can stop thinking about functions as just having a name you have to start thinking about functions having a signature of name plus arity plus guard statements as we're going to do later yes and you'll exploit that to great benefit so we'll see later how we can define function we can almost think of it as like overloading a function but really each function has its own unique signature and the virtual machine will use pattern matching to figure out which one to invoke and then here's just a simple example using the capture operator this one's a little more explicit let's store this as a variable first so if I have some list then I want to filter over that list use tap complete to explore the enum module with the h helper with a bunch of building functions so I want to filter a list and then filter is going to say give me a function and if the function returns true it's going to give you a bad arity error let's see what did it get mad about oh it's going to pass the element in so if the element was truthy it's going to give you everything back so if you just passed in the element everything's true and elixir just like the only thing that's false in elixir is nil but we can say in erling we have a build in is number function so I can call it is number on that element and it's going to filter that list and I only get one and two back but since that's such a trivial operation I can use the capture operator and instead say ampersand and I don't have to use parentheses if I don't want to here I can say capture that is number and pass in the item and mad misspelled so anytime I use the shorthand function syntax it will almost always be cases like this where it's trivial and I have a single argument to the function so if you ever find yourself ampersand 1, ampersand 2, ampersand 3 that would work if your anonymous function took three arguments but for me then your code starts getting spaghetti like to me so be a little bit careful with that I have a warning you sparing me oops we went over capture functions and then we can pass captured functions directly as like a second argument so like reduce and map always take a argument as a last operation to perform some transformation so if I want to add or reduce 1, 2, 3 just like reduce and ruby I can pass in kernel plus captured already 2 it's going to add them together so you use capturing quite a bit if you ever want a reference to a function to invoke later here's where we get into modules which we'll write a little bit of so modules and elixir are going to live most of the code you write are going to be modules so you're very rarely going to be defining your own anonymous functions to perform some work we'll pass anonymous functions to some modules as arguments but very rarely we'll be defining like add usually we'll define a module and then define this is referred to as a named function so like Celsius to Fahrenheit and this example is going to be a named function not to be confused with anonymous functions and we can see we have like def module so we define modules we get a name which is camel cased and then we give it some code between do and an end and just like on that if statement if you wanted to write a macro around this or get at the internal representation that do all the way between do and end here so all of this really is syntactic for a keyword list of do and the value of all that code so once we get into macros I'll touch on a little bit this afternoon it's a little bit advanced but we can get at that representation of code very easily so everything elixir is built up from some very simple building blocks and it carries out throughout the language so you have like if do end def module do end it's very similar all across most of its building blocks of the code that you write so we can just copy and paste this directly into IEX and play with it so you see that it said okay give me a tuple back the name of the module weather and then like all of this crazy stuff right so that's actually the bytecode so compile this elixir is a compiled language so you're literally looking at like the bytecode of that weather module if you're curious then we can call it so if I want to say give me Celsius to Fahrenheit tap complete is your friend so if it's 31 wait Celsius to Fahrenheit there we go, 32 so we invoke this is very similar to Ruby we invoke named functions without the dot notation and this is how you would write most of your code you would write it on modules and invoke the functions very similar to like a class method in Ruby so this should look pretty familiar and then parentheses are optional as well so if I wanted to invoke it like this clear the scroll back that'd be totally valid I get 32 but we define functions with def so if you're coming from like a closure use a def like a lot of lists use def that's how we define name functions so we say def the function name and then arguments and then do and again is syntactic sugar for a second argument of a keyword list so we have two ways if you ever have a single line to like you can perform a tiny bit of work in you can literally just write it like this and this is actually the preferred style if you have a very sustained function so if your function fits on a small line it's doing something very simple say def high comma do and then give it a value and again this is just syntactic sugar up here for the do in so if you ever have a multi-line function you're going to want to use the do in a very short function as a single line you can throw it in the single line syntax here so constants will let me see if I actually I think I do this in the next section we have a similar mechanism the constants let's go back we'll get to it a little bit later the constants are actually we prefer them as like module attributes which are kind of synonymous so let's hop into pattern matching a little bit we've seen some examples of pattern matching but just to show you a little bit extra of what's going on we want to pattern match on like a variables value this trips people up sometimes so if I bind A to 1 and I want to actually pattern match on A's value and not re-bind it so if I want to say A is 1 and B is 1 if I want to say does A match B we say like well we have an equal sign it's going to match the thing on the left or the right if I did this it would actually re-bind A but if I wanted to pattern match on the value I'd use the hat operator what's referred to and it's going to match on it people from Erlang really don't like this because they like single assignment so if you accidentally left off the hat operator you would end up blowing away A and re-binding it to a value now we should be able to write our first program in a text editor we'll go into control flow first so we saw if before pretty self-explanatory we have if else and we have unless which is awesome but there is no unless else by design so if you have unless else in Ruby and you write it a lot you should probably stop so we have a con keyword so if you ever find yourself like doing if else if else if else in Ruby Lixar can't do that you literally get one if and you get one else there's no else if so what you would use instead is con and con takes a series of boolean expressions and it's going to evaluate the first tricky clause so if I define a variable name temperature I can say con and then just start some clauses and the first one that's truthy it's going to evaluate and return the result so we see that it was freezing I don't think I've actually ever used con in any code for real because I'll use case instead but con is there and it's pretty handy but most of your control flow is actually going to use case and you're going to use very little if statements in a Lixar much fewer ifs than you would think because we use pattern matching instead to do a lot of our control flow and that's where case comes in so case is control flow based on pattern matching so we can give case an expression that causes instead of to evaluate as like truthy it's going to actually pattern match on the thing on the left and the first thing that actually matches it's going to call the calls on the right so for this example here we can again just copy and paste this into IEX I wanted to make like a very simple parser quote-unquote in a Lixar that's going to operate and do some expressions I can store the anonymous function that calls case on some couple expression and I can pattern match on the operator and some values provided and it's going to cases that go from top to bottom on each of these patterns and if it finds a match it's going to evaluate the thing on the right hand side so I can say okay let's invoke calculates pass it a tuple expression let's say if we have parsed some user input and then we probably cast it to a plus atom which we shouldn't have done that I mentioned before let's pretend that I use a string for this example so let's say we parsed some user input from a calculator and we know that we have the operator plus and we have a couple values we can call case on that expression which is a three element tuple first element is the operator and it's going to literally go from top to bottom here and try each of these causes out pattern matching on each thing first one that matches it invokes the thing on the right hand side if we give it something that doesn't match any of our clauses like a four element tuple it's going to blow up with the case clause error something that matches always so a lot of times you'll end up with an underscore dash rocket which just says I don't care what it is but I want something to match and you can do neat things like short circuit so pattern matching isn't just pattern matching and binding to variables this is a trivial example but let's say if I had some expensive operation and if someone passed in a zero I know that this is just going to be zero I don't want to perform any operation so just to give you an idea of pattern matching it's not just like binding variables we can say if you give me a multiplication number and then a zero I'm going to do a short circuit and say well I know that's zero this is kind of stupid but it gives you an idea that we can pattern match on a provided variable say num1 in this example right here can be anything whatever it is if the second thing is zero that you passed in it's going to match the clause and give us zero back so you use case pretty constantly if you find yourself doing a bunch of if-else almost I'd say 80% of the time be done better with pattern matching in this example if you had the other multiply num1, num2 if you had that before the zero would the zero would never... yes that's a very good point so once we get into modules the rule almost always applies it's going to pattern match from top to bottom so if we define the multiplication above the num1 and zero we would never invoke that num1 zero clause even if you passed zero in so it doesn't look through the potential matches correct it goes top to bottom the first one that matches it's going to invoke and that's actually really important once we get into pattern matching on function names because if you were writing a recursive operation where at the end you wanted it to stop but you define it afterwards you would have an infinite loop but we'll go through that so arity here this would be a single arity function because we're passing it a tuple so you don't have to define so like function here takes a single argument expression and then here we're just passing in a tuple so a lot of times people get around arities by passing in like a list and the list could take any number of arguments but it's a little bit more verbose right here so if we use the hat operator so we can actually see that so if I here if I just said like var zero there or something it would just if something matched that clause it would invoke this thing on the right but var zero would be bound to whatever value they passed in but how we defined var zero outside of the scope like up here and then we use that hat operator var zero that makes sense so anytime in your case statements if you ever want to match on a variable's value use that hat notation that makes sense and then here's like the issue if I don't want a case clause there if you give me something that I can't match against it's going to blow up and say like whoa I wasn't able to match anything crash so a lot of times we'll just use like the underscore to say I don't care what it is and then it's going to invoke this clause so if I can't parse we can say you know raise an error unable to parse the expression so this like underscore notation is used quite often as like a catch all clause and that will always be last because if we had this first at the top it would always raise unable to parse yeah so could you use that underscore in your like match cases and then do like your symbol plus comma underscore and then make that a function to just be everything else that catches yes so you're saying if we had like some expression maybe it took a plus and then if we passed it like seven and then like whatever else um you know sevens aren't allowed I'm really bad at examples so your client gave you these requirements they normally do and uh otherwise I don't know wait so what so what are we trying to do then in this example if you did seven and then anything and then you did seven oh yeah you're totally right so let's just do yeah it would have never matched it would have uh the compiler would have taken it but it would have been pointless right okay so yeah this is so this is totally valid if I call calculate sevens aren't allowed so you'll actually you'll see that under bar and it works in any match anywhere and that's for cases where we can discard a variable and I use I use this constantly in my code where if I'm going especially when you're writing macros if you have some like three element list and your api for some reason is always a three element list and the last thing is some like expression that you want uh you'll very often uh see like it's called like discarding that like we don't want to bind that to a variable in the compiler if we ever if we did that bind that to a variable and then didn't use that variable we get a warning in our code it would work but then we all hate warnings I get them constantly in my rails out for like some XML library so you know rake routes spits out a compiler or a runtime warning that sticks me up uh you actually could use anyone plus underscore okay you probably wouldn't want to it's a convention it's a convention for saying I don't care about this and it's a way to stop the compiler compiler will never complain about underscore like you didn't use underscore you won't get a warning for that um if you find yourself doing that I wouldn't do it um but initially I thought that it did literally discard it um but then in your code you actually can use it um if you wanted to be it's actually that's a good question if I wanted to say yeah but if I wanted to say I have some first uh second and the third thing is some uh value that I want the common uh thing you'll see is uh using an underscore in front of the variable this is an idiom in elixir uh if we define this in one of our functions that did not use first and second without using the underbar in front of it the compiler would warn us saying you have an unused variable first second you didn't use them but if you wanted to discard it but name it because it makes the code more clear so if that was a better example than first or second very often you'll see a discard but you'll name it just to make the code more clear yeah if you only use the underscore in line 37 as both the first and the second item in the list there doesn't that force it to find the same value for the first and second yeah but we don't ever reference the underscore it works um but you would never actually want to say what was the value of the thing I discovered well no but what you were showing up there was open square bracket under comma under comma val could that in close square could that actually match 1, 2, 3 yeah so let's see let's actually see what happens I could eat my own words here so if I say okay that matches we expected like what's the is this gonna give me a value no it actually doesn't like that so I lied I think this works though if I discard or if I say first here I thought this was a discard as well which it is but I think I can actually reference underscore first yeah I can so that's yeah so the compiler would warn if we in our function had a first that we were binding but not actually using so you would prefix it with an underscore it is actually binding that to a value but the compiler will stop warning you so you can still reference it you if you ever find yourself referencing a prefix variable name with an underscore remove the prefix because it's just odd because it means the intention is we're discarding this yeah it's not treated differently it's a convention the compiler will warn you so it is treated a little bit differently but we can still reference it I don't know if some of the internals optimize around it but you could we just we have a variable underscore first that is bound to a value but the compiler would actually warn us otherwise so the compiler treats it differently semantically I don't think it actually optimizes it out at all so you're saying that a single underscore is treated differently than a variable name that begins yes single underscore literally is a discard a variable that begins with an underscore you can think as a discard but if you wanted to reference that by its name you could but you wouldn't want to especially since later maybe they would optimize that in some way and if you had code referencing that I'd probably consider it a little bit unsafe and here's what we get in the guard clauses which are awesome is anyone familiar with the term like a guard expression in Ruby I use this term all the time so like the top of my Ruby methods often instead of like an if else or like an if case and like write your code in your method and then an end you'll just have like a guard statement at the top I think a lot of people use this terminology in Ruby so like if I my method receives something in Ruby that I if it doesn't satisfy some case like the user doesn't have access to perform some operation I can just say like return unless is admin user so those are like I refer to that term guard expression in Ruby and conceptually it carries over into elixir but it's a little bit more powerful here and it's highly optimized so in like a case statement I can give a guard expression by using when so here's our calculated expression again which if we try to divide two numbers in the prior implementation it would blow up with a divide by zero error so I can I can define a case statement who also has a guard I can say okay I have a division operator number one number two when number two is not equal to zero then go ahead and invoke the division so this would define a signature that literally if you passed a zero as number two a clause would not exist that matches that and this is like super highly optimized and I use this all over the place in my elixir code so if we tried to call like calculate 10 divided by zero we get a case cause error that we actually don't have a case defined matching 10 over zero but they're a little bit restricted so we can't call like our own functions here if I define into function that was doing some my own define functions it would actually blow up it's limited but it's highly optimized so in Ruby we have a guard statement that calls any code anywhere the actual guard terms in elixir are defined to a subset of operators and a subset of built-in functions but you can't call like user land code I have a giant list here if you want to look but they're pretty cool on name functions because like if I had like a bank system so if I wanted to define like a credit function so you have creding and a balance in amount I can say like credit balance some amount when amount is greater than zero and this would literally the function signature here would be arity two but the guard statement would literally define the function only for when amount is greater than zero so this seems just like an if like return in ruby but you have to start thinking about this like this function credit has a signature that's all three name arity plus guard statements that define the actual function that the virtual machine ends up invoking and there's a huge list of functions that you can use most type checking functions are available in guards so I can say like if I was having a grading system you know death grade passing a letter when the letter is in A or B they did well let me see some more practical examples what does it mean that a function is not defined on the last one of the arguments like what it means is not defined but the virtual machine when I invoke a function it's going to pattern match on the function name and arity in any guard statements okay so when you're invoking a function internally the virtual machine is literally pattern matching on this thing so the function is there it's just like oh it's like match the pattern so I'm just saying conceptually it's defined I'm trying to make you think of in terms of pattern matching so when I ask the virtual machine to do something it's literally going to take a module and try to pattern match on those things and if those don't match as far as it's concerned that doesn't exist as far as code that it shouldn't invoke so now we're getting to one of my favorite features so it looks at the pipeline operator is anyone familiar with anyone do closure here similar to like a threading macro in closure I think this is actually stolen directly from closure's concept it's the first time I've seen this and it's amazing so a lot of times when you're writing functional code things that I hate is you almost have to write code and read it backwards you're familiar with any lists in addition to the parentheses you end up having you're trying to define a series of transformations you have to almost write it backwards because if we want to pipe or use the value of some transformation and send it to the result of another function we end up having to write our steps from like the center pass that in, pass that to another function pass that to another function and it reads backwards from the actual transformations that you're performing so the pipeline operator exists in Elixir to pipe a value as the first argument to a function and so here's a a trivial example I have like IO puts right hello I can actually pipe this instead and say okay I want to pipe the string hello into IO puts so we use the pipe greater than and that will literally make transform that into IO puts first argument hello but the neat thing about this is you can have still any number of arguments and pipe this value so if I have like an enum map operation which takes a list and a function I can have a a list and then I can pipe that into enum map so enum map takes a list normally as a first argument and then a function as a second well since it pipes that as a first my function becomes the first argument here I can say i times 2 and it works and to me this is seriously my favorite this and macros are my favorite feature of the language so if macros didn't exist or the pipeline didn't exist I don't know that I'd be talking today so this is one of the things that really drew me in early on because this lets you describe your programs as a series of transformations so I'll get through probably my first real world use case here so let's say someone comes down to you and they have a list of requirements for a program and they want you to hit a third party api so we have some user token we want to hit the api with a user id get a token back, authorized user token for it maybe some like OAuth api then we want to make a json request to an api with the authorized user token then we want to save all of those json results to a database so it's like a four step operation if we wrote this without the pipeline operator we want to import some new messages under the requirements I just described so we have important new messages maybe we have some OAuth user token we almost have to write this backwards and then reading it it's not like we can use indentation this isn't too bad to read but you can't grep this in your head or grok it right away at least I can't so we almost have to read this backwards and go outside in it's like okay take a user token here call find user by token that's going to give us back some authorized user token that we can then fetch from the api maybe some unwritten messages that's going to give us a json result which we then want to parse to some messages in our program and then we want to iterate over each of those messages and call save message right so yeah so it's like I don't know it's like for me that takes way too long to reason about so that exact code exact functionality with the pipeline operator becomes this I can say okay and this is how I write almost all my code I can say we start with a user token and we're going to actually transform that into some user and we get that result which is an authorized user fetch their unwritten messages that's going to give us a json result parse a json message list pipe that to enameach which is a list of json or json array and call save message so is everyone clear on that like literally this is the same same function signatures here yeah so yeah here you would need on everyone and you could put this at the you could pipe at the end of the line it's my convention to pipe in this manner some people will pipe at the end looks are so new yeah it looks are good that's a good question so there's a lot of discussion around if like the third operation like trying to make the fetch for example that failed what do we do some people would say well your program should crash and it sounds funny but like one way you would handle this is this operation would be supervised by a supervisor which we'll touch on later and you would want this to crash and if this crashed we wouldn't handle it at the supervision level which would then maybe retry and maybe the api service was down so your supervisor could have logic that would say retry this times over a minute period if that still fails and the supervisor would actually crash and then its supervisor would figure out what to do so that's one way but in a lot of cases you're not going to want to supervise everything so there's a lot of discussion around and looks are how we can best handle this so looks are recently exposed a way to easily write macros around this we're going to do a little bit this afternoon in the use case but there's some mechanism in the language you could find a macro to handle this error case easily and there's a lot of discussion on the looks are mailing list about how can we actually do this in the language itself so some people are suggesting you would pipe into like if okay and then some other mechanisms that's a good question so hop on the looks are laying looks laying talk and looks laying core google mailing lists and there's a ton of active discussion and there's some differing opinions so looks are is so young we mentioned like conventions of the pipe operator where to place them it's so young that you can get in early and define some of your own conventions we all use two space annotation hopefully so some things are set in place but it's still up for opinion so it's kind of a fun time to be involved but piping is literally one of my favorite features of language and I'll show you a tiny bit of real world example just to say so I'm working on a web framework in a looks are and I'll just hop into like a random module that I have we'll see how many times I use the pipe operator so I'm not going to explain this code but we can see like right away I'm piping so your programs become a series of data transformations and the pipe operator literally exposes that so it seems like such a simple thing it's the same code but it changes the way I think about programming for some reason I don't know why so it's almost like I start in my programs I start with some string path I ensure that it has no leading slash then I split it like it literally just the fact that the pipe exists and flattens my transformation layer out I start thinking about my first with this method I wrote path down and I said like okay what do I need to do with it well the first step of the transformation would be leading slash then split it so like you start thinking about it as a series of transformations just by virtue of being able to flatten your steps out like that no so it's actually really good so there's a pull request that was just closed by jose for people that wanted to be able to do that to say I want to pipe to the second argument instead of the first or I want to pipe to the last argument so there was actually one discussion on the mailing list that was like I want to be able to say like regex dollar for like basically Dave Thomas if you're familiar with Pragg Dave he ended up finally chiming in as a voice of reason saying like we've developed a terrain complete language as a pipeline operator like people were like it was like well plus dollar that would do something like so most of the discussion and I'm with this I would actually prefer it just stays as a single pipe like that and always pipe to the first argument some people like this option to pipe to the second because a lot of Erling libraries if you're trying to do Erling interop will pass the thing that elixir passes the first argument is almost always the subject of the function so elixir code lends itself to always piping things to the next thing like the thing you're operating on is could always be the first argument and it lends itself very well to piping but Erling doesn't Erling just is a mix and mash it's kind of like the I took on php like a php center library it's kind of like needle haystack haystack needle who knows so Erling is kind of similar there was never a convention originally so a lot of people want to be able to do the pipe greater than greater than for a lot of Erling interop because otherwise if you wanted to pipe you have to write your own function that wraps the Erling function but I'm of the opinion that we need to keep things simple because you get carried away like what like what Pearl did and like you get to it's all clarity of a brevity thing so much that we end up with this like turn complete language in like a pipeline operator so yeah it's awesome so I'm a huge space nerd so my first real program real program is a rocket launch because rockets are awesome so if you have a text editor copy and paste this in because I'm going to show off a little bit of IEX feature it's nice so we can define a module let's just go ahead and paste this into your favorite text editor so if you name the file .exs Elixir files are named .ex and .exs .exs stands for like elixir script so all of your code that you're going to ship to production is almost always going to be an .ex file .exs are compiled to be bytecode and .exs is an elixir script that you can run and it will compile it in memory and execute it but it won't spit out a bytecode beam file so if you had something you want to do scripting wise you would do .exs so then you wouldn't end up with this bytecode compiled in your directory that you don't care about so for like simple one-off programs .exs is awesome so like a lot of cases where you would just write a simple ruby script do some like sysadmin related thing you would make it in .exs because we don't care about the compiled bytecode we can just discard that after it runs so we can save this as .exs and if we fire up .exs in the directory that you saved that file I've got to quit out and see where I'm at here there we go, fire up .exs in that directory and then you can oops if I type h and look up c c is a helper function that takes a list of files or a single file and it will compile and pull it into .exs so if we save that as .exs I could say c .exs and it compiled and executed my program because I had a rocket start launch sequence so I'll give people a couple seconds to get that pulled in so if you want to play with code without having to copy and paste the source in IEX as we've been doing all day you see to bring it in compile it so then we have access to our rocket module and we get a lift off statement so we can actually walk through that code a little bit can't remember to read that or make that bigger good so we're going to do a little bit of recursion here which is we don't do much recursion because I didn't so the goal of our rocket is to count down from some what's the error did you give it single quote or double quote around your that's actually really good I should have mentioned this before single quote is a character list so Erling has a historically poor string handling support as far as like Unicode support is concerned so Erling strings are defined with single quotes so it kind of ends the debate Elixir ends the debate of single quote versus double quote what do I do in Elixir it's almost always double quote but you can still use single quote for Erling interop it's going to be a string of characters so if I pipe this to enum at zero give me the first element of this list I get 115 so what this is as a single quote it converts the single quote of string into a list of ASCII integer values so a lot of Erling libraries will use single quotes but Elixir almost always uses double quotes which is a UTF-8 encoded binary string so pretty much always use double quotes when you're writing Elixir code but if you're trying to go for Erling interop you'll have to call string.toCarList which we don't really need to get into right now but if I want to convert my name into a character list to get the single quote version I have to actually convert that and you'll get into that when you're doing Erling interop we can go to a character list or from a character list and with Elixir we always use double quotes and that worked for you now with double quotes it was actually a great question I'm glad you had an issue so bang in where did I oh okay so bang in Ruby we kind of use it for two ways bang in Ruby is either mutation or it can raise an error at least I've heard people use it never ever use a bang unless you potentially raise an error and since there is no mutation I guess there's no other interpretation of it so bang in Elixir is saying I may raise an error and there's a version of ToCarList without the bang that returned me a this is called a tagged tuple so a common convention in Elixir and Erling is to return a tuple from a function and the first value a lot of times will literally be okay saying like this was okay this worked and then the value that I requested and then if it didn't work I'd have to paste in an emoji can I do that from the terminal oh my gosh it worked okay so if I want to convert this to a character list um okay it shouldn't have worked so Elixir has actually fantastic emoji support and I wish I wish I could I gave a macro talk at Erling Factory and I showed how this is done at compile time it literally takes the entire known like Utico database and compiles it to a bunch of pattern match functions so like there's a a ton of functions dealing with emojis because they're just Unicode code points so every emoji that exists Elixir can mutate and handle properly whereas like Ruby if you tried to pass an emoji to a stream it freaks out so there's fantastic emoji support which is just great right in fact like even in Ruby I'll give you an example in my Erling Factory talk if I want to take the string Jose oh man where's my option 8 option E option E yes okay so if I want to upcase Jose and Ruby it's like ooh doesn't quite work right the E is an upcase so I wonder if like Jose has such great Unicode support because his name has a Unico character I don't think so but I'm going to use this to pick on Ruby a little bit because like this is so trivial we should be able to upcase strings in Ruby 2.1 properly and that fails such a trivial thing you know we test this out in Elixir I pipe this to string upcase BAM it converted that E to a capital letter and it looks so trivial but this is huge I go to any mainstream language today almost all of them fail upcasing that code point and Elixir properly maps all these things and it does it in a very neat way that if we have time this afternoon I'll show you that it's taking like a flat text file and then defining like thousands of functions off of it pattern matching on like the lower case E and then returning an uppercase version so our rocket module is just has a few simple functions that does some recursion so we can see we're kind of tying together some concepts we have like a start launch sequence which is a public function it's the first time we're seeing def p def p is a private function so we wouldn't be able to invoke that private function outside this module and it's my convention to define my public and private functions by each other based on where I call them some people throw them like in Ruby a lot of people it's like you say private and you list all your private functions I mix and match based on my needs so we have like a start launch sequence public function and we get this default 10 second argument here so this is a single start launch sequence but I can call it with zero arity because I give it a default of 10 and the default notation is backtouch backflip which some people frown upon saying like what why is that and one reason is because our equals operator like in Ruby we would write it as from equals 10 this is a pattern match you're pattern matching on from equals 10 so if I recompile this, this is totally valid let's go back I'm trying to call, here we go it's going to warn you that you're redefining the module that's normal so if I want to call start launch sequence again it no longer has a default argument so it's going to blow up if I try to call it but if I try to pass in like 20 there it blows up because it was performing a pattern match if I pass in 10 so equals is not assignment here it's a pattern match equals is always a pattern match if it's a variable on the left hand side it will bind it to a value if you pass in from and it wasn't 10 it will perform a pattern match of the thing on the left thing on the right it will blow up with a match error so is pattern matching like that ever useful? extremely useful like in the parameters like that? so instead of writing I'll try to give you some examples instead of writing a lot of if cases in your functions we could define multiple here doesn't make sense we could define multiple start launch sequence functions each of them pattern matching on a value and invoking that function based on the pattern match instead of like if this do this else do this does that do that from top to bottom? yes so if you have like depth start launch sequence 0 it would just do lift off and then depth start launch sequence from exactly this is actually both your questions so what our launch sequence does once we get rid of the whatever variable they pass in is 10 I can call countdown and countdown is defined twice so if we countdown in our current count is 0 we call blast off otherwise it's going to be some seconds we don't care what it is we print out what the current number of seconds are and then we recursively call countdown passing in seconds minus 1 so in this example I'm not actually storing this as a value but if I was doing something with seconds I could say seconds equals 0 here and that would be totally valid so you use, you bind variables with pattern matching in arguments all the time so instead of like in Rubykill we might say well if seconds is going to be 0 like a lot of like Perman 101 recursion would say ok what's our the case where we need to actually spit a value back and we call blast off but we don't use if statements but we could but the pragmatic approach is we're going to use pattern matching as your program reads almost as a series of specifications versus using explicit if control flow so instead of like all these branching conditions your program literally from top to bottom this is a very simple example but from top to bottom immediately I know if I pass 0 to countdown I have totally different specifications I'm blasting it off I have countdown that's any number of seconds and I evoke some other so is everyone grasped at least the recursion and pattern matching in this example pretty simple but very powerful and then we, yeah how do you decide? so in my personal opinion if you can pattern match almost always pattern match because the conditional and the function I guess comes down to style but for me the virtual machine has been optimized for pattern matching for two decades and it lives up is the heart of like all the code that you write so instead of thinking about your programs as like conditional branching literally by defining them in pattern matching it changes the way at least I think about code so it comes down to style but if this was like an if else case for me that would be harder to parse than reading through some pattern match definitions but it's style but I would say at least the code that I write has very few if logic branching because I'm using pattern matching instead but it comes down to personal preference and then here we have a guard statement start launch sequence I could say when from is greater than 0 and when from is less than 20 and that would literally define a function that only responds to those cases so if we go back and try to, I gotta recompile if I try to invoke this for like 24 it's gonna blow up with a function clause error so literally as far as the virtual machine is concerned no function exists to invoke start launch sequence 24 and that's the way I want you to start thinking about functions is like they have their own signature yeah Is there a way to list out for a given function name and the arity in a logical what patterns will match? In what example? Well in this case there's a condition that this definition that your cursor is on can only match when from is greater than 0 and from is less than 20 so would there be a way to query the system and say I want to know under what conditions there is a match for start launch sequence arity 1? I see, it's a good question let's, we can say I don't know if you can get that granular there's some metadata defined on the module by Elixir, like this special underscore or info but we only get arity so at compile time if we wrote a macro we would be able to get at that and look at what they were passing to win but at runtime there may be some tricks but I'm not aware of it I mean it obviously exists the virtual machine, yeah it has some logic to go but that's beyond my level but maybe there isn't that's homework, you find out what we know yeah, so you're saying like we have countdown twice here when I call countdown here like how does it know what is a good call so functions are defined by name and arity they both have one arity, they both take a single argument but the virtual machine's got a pattern match from top to bottom so when I call countdown right here, countdown was 10 it's going to say okay function pattern match, the name is countdown value is 10, okay that didn't match value here is 10 well it's just going to bind to a variable so it's going to invoke that definition I pass 0, it's going to pattern match from top to bottom 0, this is where pattern matching comes in where it's almost overloading but not, it's really defining a function with a signature of name, arity then we can have some guard expressions does that make sense? so if I defined countdown below like this since the top one is more generic it would go forever so we can play with this oops so that's one thing to keep in mind, you want to go from more specific to less specific oh did it? oh, yeah yeah, you're actually right so it will warn you that yeah if you ever see that, you probably want to take a look for that exact case yeah yeah, the compiler is going to warn you that you have an ambiguous clause so I notice that you are just doing seconds minus one you're not doing seconds like minus equals one so there's no mutable state in this, is that right? yeah, so elixir you're talking about a stack like ten times or something? that's actually, you guys are like perfect with questions because I'm forgetting to mention stuff yeah, so if anyone is familiar with tail call optimization this is tail call optimize, so as long as a function ends in another function call it's tail call optimize so there is no stack overflow cases, so it's going to tail call optimize that, it's not going to build up all these things on the stack, it's just going to tail call optimize it yep, go ahead it's the does it count down helping friend zero, both friends would that be the same as saying does it count down of seconds when seconds equals zero? yep, okay, so you're saying I could say and then like this? yeah, it would be synonymous it's running the same as doing seconds equals zero inside the parent so you're saying seconds equals zero here? yeah and then this should work it wouldn't be entirely necessary because we don't need that value, but yeah so yeah, yeah, so it's like, it's one of those cases where both the win guard and the assignment is unnecessary, we could write it more succinctly without but yeah, totally valid, so win begins, you can make something more specific just by using a guard clause it's like you're saying like if I had the function signature could look nearly the same like this, but that's still more specific because of the guard clauses, and we're from machines fine with that, everyone good on this? any questions? with the recursion? I have a question regarding guards and Alan, it's not allowed to use a function as a guard yeah, so we couldn't, let's say what's a good rocket term here, so you're saying if we were going to have like is about to explode and we're really pessimistic, so yes, always so we're saying if we were counting down and it's zero and you're saying if we want to say is, when about to explode oh, is we can't do that it will not let us, so it should actually give you a helpful warning, is that your question if we try to do something like this? yeah so we're restricted to yeah, cannot invoke function cannot about to explode inside guards, so we'll pick that up and warn you, that can't happen so this is where you would have to either write an if statement in your function or often times instead of ifs I will write another function that will then pass is about to explode the value of that to countdown so then we could say is about to explode as a first argument and then we could pattern match on that and say oops I could then discard it to be explicit and then we could still get that pattern matching nicely without ifs, ifs, ifs that makes sense but no, we're limited to, I have a list on the previous section I think it's exactly to be honest with our link, we have all those type check functions we can't use like the and and or like or operators as to be the boolean and or and the reason why we're limited on guards is because it's really highly optimized so we can't do our own function definitions because then it would literally have to invoke those functions and we kind of lose performance but you could write a macro if you do this so if you wanted to get really fancy you could write a macro that literally would look like is when about to explode and you can compile that down to like an if and do something crazy and it would look exactly like we saw but macros are amazing but then it's a whole like with great power comes great responsibility we went through guard causes here's a, I'm not going to type this in but we had like that case expression on anonymous function before it's kind of neat that anonymous functions can take multiple function heads and pattern match on each value so this is almost like a case expression I had some like process input function that took like a command and like a number of spaces that the player wanted to move I could say that process input is equal to anonymous function fn but then I can give the function multiple function heads and it would pattern match on each of these almost exactly like you would write a case expression and would evoke the first one that matched so that's kind of neat so you could give like an enum map pattern match on a bunch of function causes and do something neat with that those are just like a separate function yes, correct so it would be like I have that still I have an example of this I don't know if this is going to be very clear but like I'm trying to do some transformation I can pass the enum map here and then I'm doing some weird syntax doing some like binary pattern matching on a map operation and it's going to whatever one matches, it's going to invoke the resulting map operation so I use this in real life you're not going to use it a ton but it's still pretty neat that it exists yeah, I mean, some cases I would probably recommend just piping that calling a function instead of giving it multiple function heads but literally since I start fn right here at the top I have fn and then I have n and then anything I put in between is almost like a case block where I have a dash rocket thing on the left is the expression thing on the right is the function body exactly so that's pretty cool and then we can get into our modules can alias things import things and there's a require keyword as well and these let you do things pretty self-explanatory so if I have like a converter module and I want to alias an Erlang library it's by like Adam so Erlang the math library I want to alias that as something more elixir friendly like capital M math I can define a converter and say alias I have this Erlang module math I want to say alias that as capital M math so then anywhere in my module I can then reference it by capital M and then if I want to import functions from another module I can say okay import from that math library if I leave off any second argument it's going to import all functions otherwise I can say import okay only give me the pi function erity 0 so you can like selectively import functions from module I think you actually have to explicitly spell out the erity and you can do that so one thing one reason why keyword lists exist is because they let us define multiple keys of the same value of the same name and that's totally valid keyword lists some people are like that why not use maps instead which maps just line in the language which are just like Ruby hashes but keyword lists are still really nice because we can store multiple keys of the same key but then we can have different values and it works out really handy for doing things like importing when we have a function of those named pi pi never takes a second argument but if it did we could say import pi 0, pi 1 and then we can reference it like math cosine we aliased it and then pi we can call directly because we've imported it so pretty simple but you'll constantly be aliasing and importing things one thing that trips people up initially is Elixir has no menu spaces other than what you define yourself so I'll show you a real world example I have a framework I'm working on it's called Phoenix it's an Elixir web framework if you examine any code in here you'll see like a ton of aliases so like I have that router dot mapper that's just my own personal namespace so I don't have any name clashes but then I have to alias any other Phoenix router namespace because it doesn't automatically know that it's in a Phoenix router namespace that makes sense so I have like Phoenix router errors is another module if I want to reference errors within my Phoenix router mapper I have to actually alias it first so there's no automatic namespace awareness you actually have to create aliases for that and this looks like a ton of aliases normally you don't get into this many but the Phoenix router is doing a ton of metaprogramming so it's a little bit complicated yes perfect because I would have forgot that so alias by default if I leave off any second argument this is synonymous with saying as path so if you leave off a second argument it's going to automatically assume the last dot whatever is the thing you want alias perfect question it's actually I don't mind it but coming from Ruby a lot of people initially are like all this boilerplate just to use my own modules but it really impractical isn't too bad this reminds me of hyphons import and I was wondering just estimation from somebody who's more experienced how hard would it be to write a macro that takes like a namespace and then just list off a bunch of things that you want to alias from that namespace that you could write from phoenix router oh I want to from phoenix router use path resource context go context errors map error actually it would be trivial I have never considered that but I think that would probably be a good language addition all these three things should be able to take an array or something so yeah the actual macro if we have time this afternoon I touch on macros but it's a whole another topic and very difficult if we have time I'd love to explore this because it would be a very simple macro to do that just to give you an idea of phoenix I just want to plug it a little bit because we have a bunch of rails folks here this is a phoenix router and it might look very familiar to you coming from I'm not trying to recreate rails entirely but elixir does give us a metaprogramming and macro system that lets us do like resources users do resources comments and we can then generate a bunch of code at compile time that does a bunch of neat stuff so it's very cool and here's my next section is actually macros but this is not an exhaustive list I debated whether or not introducing macros because it's a pretty advanced topic but I want to get people a little bit give them a taste because macros are why I'm here today probably I love metaprogramming and Ruby I love being able to find a router like we do in rails so if elixir didn't have macros I guarantee I wouldn't be staying here today so I'm going to give you guys a little taste so macros essentially are just code that writes code if you've ever heard that terminology so let's pretend in elixir that the unless keyword didn't exist they just give us if and you say I come from Ruby I have to have an unless keyword and we can write that so we can define a module macros have to be defined in modules which we can then import into any namespace so I could define a condition module and here I named it lest instead of like I could override elixir's unless but I could say like less to be like I don't know, unique so I can define a macro with def macro and the most important concept with macros is macros they look just like functions right we have a couple of arguments but macros get the actual abstract syntax tree in elixir so instead of getting some like Boolean result as an expression they will literally get the AST that we can then manipulate in elixir so I can get some condition expression that someone gave me I can then generate my own AST with quote do some AST manipulations and convert it into an if not expression of what we do here and let's play with that before we jump into what that's actually doing so in elixir quote is going to take an expression and give you the actual elixir AST back so I can say what is one plus one in elixir actually so you're looking at the elixir AST so when you compile your code this is the abstract syntax tree and the neat thing about elixir AST is it's in all elixir's own terms so elixir can be entirely represented your elixir source code can be entirely represented in elixir's own data structures and that makes it insanely powerful to write metaprogramming and get any code representation in an elixir's own data structures we can then evaluate it at compile time do whatever we want with it manipulate it, generate some other code from it and it's not any extra special syntax so like one plus one we can see is a three element tuple so I won't get too granular but all of your elixir code everything you write compiles down to a three element tuple in the AST first element is the function name and then the second argument's metadata so we can see the context is kernel and the last argument is the arguments to pass to the first argument of a plus so if you're coming from a list background like this blew my mind elixir has a built-in div keyword so I'm going to divide four by two get two so if I quote that you can quote anything and get the representation if we ignore this context here what we end up with is like div some metadata and then four to right I did a tiny bit of list in college but not much like this is basically what right you replace the brackets with this would be essentially what list was doing so for me like that almost like blew my mind once I realized that because elixir is essentially giving us a syntax veneer over this simple AST structure but under the hood it's just all like a simple so like lispers literally code almost the AST directly but in elixir we operate on top of that but we can still dump down get at that after a syntax tree and manipulate it so if we want to quote like an if expression we can see if I define a macro it's going to get the AST as if we quoted a value and then a macro's job is to take an AST and return AST we go into a quote because we want to return AST back to whoever called us and then we just write some elixir code because remember quote all quote does is return an AST I want to interpolate a value into the AST I use unquote and if you're not familiar with like I think like the term like quote and unquote comes from I think a list closure does it too yeah initially it might seem unusual but the best way to think about quote and unquote is like string interpolation for code so if I have some expression outside this AST I'm generating if I want to interpolate that into my quoted AST I have to use unquote so it's almost like if I had a variable on a string and I want to inject the value of the variable in the string that's what unquote does for us so I say if not and then I want to inject the value of AST directly in that spot so I just say unquote expression and then any options are just going to be the do in block so in elixir I can say if whatever comma do in and that do in is going to be our options and we can just unquote it directly in place so literally that's all that's required to write our own like unless macro so you could copy and paste this in place to play with it if I have a condition macro the only caveat is you have to require it to ensure that it's macros are in scope here in practice I don't think I've ever written I've never used the require keyword in elixir in my own code because at compile time everything is already required and anytime you import a module it is required so I've never explicitly required one in my own code but if you ever are playing with these things in IEX you need to require the module before we can actually invoke it's a LEST macro so I can say condition dot LEST five equals five do and I get no actually to be able to import condition so if I can import modules directly into the scope here so what macros give you literally just like Ruby you can make DSLs and you can literally add things to the language and what Jose has said which is really neat the best way to think about this is like programming languages over time fall out of favor because they become outdated and basically you start programming languages are written they're not mutable enough to change that eventually something else rises up to replace them but elixir basically gives us all the main building blocks to define our own keywords in the language so if some new requirement comes up later in the future and you said like I really wish that existed in elixir like if you're trying to think in Ruby like I really wish the pipeline operator existed in a Ruby you couldn't do it that I've seen but in elixir the pipeline operator itself is just a macro it's like literally if we looked in an elixir source code it would have a black macro left right do and it would transform the left right thing into a read backwards print expression so we have access to all this power directly can you quote it? so the only caveat is we can't define the pipeline operator is special that you couldn't just define your own like star star b operator specifically supported by the compiler but if we wanted to say you're saying we want to quote like hello maybe pipe it into IO puts or something grab this so this is saying we just have a function pipeline didn't really format it very well can I let me try to inspect that a pro tip is like you know in Ruby I can get the previous value in IRB using the under bar the elixir shell I can say v-1 I can go back the number of previous commands I want so now I have the result of that so if I inspect that my own spec should pretty print almost any data structure here we go perfect so we can see we get a three element tuple back three element tuple saying here's this function it's going to take a list of arguments first argument is flow which is another three element tuple so elixir itself is composed of three element tuples like I said and it's basically you know with these stacking three element tuple scenarios I don't know if we can garner too much from this but the AST is pretty easy to reason about you get really complex it becomes very difficult but at compile time you could write your own function to get at this and that's what elixir's standard EX unit testing library does there's a single assert keyword so I can say like assert 5 greater than 5 and internally in ruby this would just say if this test failed let's say if we wrote that in our ruby test it would say failure got false expected true or got true got false expected true we would get no information from that in ruby so we end up with things like assert equal and uh in elixir the testing framework is just a single assert and if this we wrote this in elixir we would say test failure we had 5 we expected 5 to be greater than 6 it's able to actually compile time maintain that information and you just assert everything and it maintains all of that structure because at compile time it's going to convert this and say okay let's just quote this because assert's a macro it's going to receive the AST we quote that 5 greater than 6 what do we get we get a very simple thing that we can write elixir code to say okay if you have a 3 omelette tuple the first element is going to be the operator if it's greater than I'm going to run a function of the assertion and if it fails I'm going to say print out we expected this thing to be whatever this thing is greater than this thing right so if I have a entire talk that we brought around a cert macro online if you want to check it out literally I'll take you from no macro knowledge to writing a little testing DSL and so hopefully that enough to see how you can go about these things at compile time you can get out elixir code in its own data structures then write elixir code to inspect that to generate elixir code and it's a whole like the first rule of macros is don't write macros you've heard that joke and because people can get carried away with these things it's like with power comes great responsibility and you end up generating your own language on top of elixir for me it's awesome but it does have to be used with care like the assert case is the perfect case doing things like a routing layer like I'm doing I think is enough of a win I'm actually trying to advocate people say write macros responsibly not don't write macros I think a lot of people have heard macros are evil so much that they're often just overlooked but you go home tonight and you go back to your random and for me macros are kind of like the future that's why I love a language for one of the main reasons so there's alias import require that's pretty much modules so we compose modules to write almost all of our elixir code we can import modules directly in a function scope so here's a simple example I have I'm just going to call it tests def run within this function I could say import math I don't do this ever really in my code but this is totally valid so only within this function scope would math exist and then I could say just return me pi times 2 so now if I ran test.run I get pi times 2 so import and alias and require actually all three are available at any scope in functions or on modules and it turns out they're all macros and I'll keep saying this everything in elixir like def module itself def module is a macro it generates some elixir ASD def itself is a macro so if I say hdef it's just def macro def in elixir source code so elixir itself is built primarily with elixir macros so if you really want to get into this read the source code and then it will kind of blow your mind because you can write you could have written this if elixir didn't have a def keyword it would be terrible it would be all of what it's doing so it literally unlocks the internal representation for you to write your own keyword in the language and for me that makes it really special coming from Ruby so there's macros it's a whole topic and I have a talk on it if you want to watch that but I don't have the whole day to go over them but they're awesome so is everyone here's where we're going to get into so does anyone have any questions before we get into like processes and holding a state and anything else that's a great question because people ask us all the time if you ask on twitter a lot of people will tell you you have to earn elixir first I started with elixir primarily with Dave Thomas' programming elixir book and just dove into it without any earning knowledge and that was sufficient to get going eventually you're going to have to jump down into earning a tiny bit if you want to do any interop so eventually I basically while learning the intricacies of elixir and OTP that will get into OTPs like Erling's standard library for building fault tolerant programs you're going to have to get down read Erling documentation and be familiar with the semantics but they're very close to elixir semantics so I recommend people if you want to get into elixir, I mean Erling's fine Erling's great but just dive right into elixir eventually once you get past that beginner level you're going to have to dive down a little bit in documentation but by that time you're exposed enough that you'll be good to go so we've talked about elixir being immutable and being immutable makes some things really difficult like what if we wanted to create anything what if we had a class that we just wanted to keep account of something our program is going to be counting the number of requests we've had per minute like where did we store that state we can't just talk, in Ruby we would just instantiate something or on the thread we would just increment a value every time something happened and that would be perfect but in elixir everything is immutable so like how do we actually hold state and this is where processes come in and processes are elixir's unit of concurrency open that real quick I live at the heart of almost everything you do in elixir so we spawn processes and processes have mailboxes so literally the term mailbox is a concept in erling and elixir and we can send a process a message and that message can be selectively received and it's received in a mailbox so I could be in my new process someone sends me a message, it's not going to do anything if I want to check my mailbox I can hop into a receive loop and say hey is anything on my mailbox otherwise, yeah no, it's not a systemable process it's a it's handled entirely by their own virtual machine and we can run like, we can spend like a million of them and so don't think of them they're like incredibly lightweight I forget what how much memory a process takes but it's tiny so you can, they're cheap I've heard, the best way I've heard it termed is you never think in an object oriented language like what's the maximum number of objects I can create in object oriented language, you never like think that same thing you should think about processes, we spin up processes for everything and they're run concurrently and we never really have to be concerned about going over some maximum process limit day to day, so they're cheap and we use them for almost everything and that's how we achieve concurrency so we can spawn a process with spawn and if we want to receive some messages we use a receive keyword so go ahead and if you have IEX running with spawn a process so PID is a concept you'll hear of like process ID so PID is going to be the result of spawning some process, we can give it a function and it's just going to spawn a process and then within this process we want to be able to send it messages so we're going to tell this process hey, I'm going to send you some messages receive some messages from me so some kind of sender sender process is going to send this thing a message saying we'll say what ping, we're going to ping it so we're going to pattern match on a bunch of receive clauses I'm only going to list one here I can say IOPuts ping I actually want to make this multi-line font is huge so within this clause I can say IOPuts ping and then I can send send it's another keyword back to the sender PID that sent me a message I can send it a message PONG so we're going to ping PONG some messages back and forth so now we have a process that we've spawned it's out there and it's running the neat thing about process is this process ID is fully qualified so if we have wireless this afternoon I could pass this process ID to your laptop if we were connected on a mesh and you'd be able to send it messages there's no it would look identical to this so that process ID is fully qualified on any network that's in a mesh which is kind of cool and we'll see that this afternoon if that doesn't make sense yet so I can ask is the process alive yes so this thing's out there it's waiting for messages so I'm going to send it a message for myself if you remember self returns so self is going to be the IEX sessions process ID I can send a message to that PID I'm going to send it a tuple so here's how like where tuples come in is like a basic data structure I'm going to send it a tuple saying well the first thing is for me so here's a message for me I'm going to tell you ping and oh my gosh it got ping and remember it's sending back a message here and then it sent sender or pong but nothing happened with pong right this is where mailboxes come in so processes and elixir and earling if you want like guaranteed there are two ways so if I wanted to make sure a process was sent I have to check my own mailbox this kind of seems like an extra step for a lot of people but the way this works is if we have a code running out on a mesh I specifically have to check when a message was received properly on a mailbox because that ensures that if that process died in the middle of me sending in a message there's no way for me to know if that actually got there unless it sent me a message back if that makes sense so in order to check my own mailbox I can say from our own process receive and then we pattern match I'm going to say I can receive any message I don't care what it is and I'm just going to return it back to a console Pong so there is a simple process mailboxes what did you say again so that process actually is it still alive so that process is gone and the reason that is receive only executes a single time so if we wanted this process to stay alive we would have needed to recurse on itself and do another receive loop otherwise it had no work to do so it died but if we sent 10 messages to the process they would all be in the mailbox waiting so they just queue up in your mailbox you hop into a receive loop it executes, if you want to go back and execute the next thing you just hop into another receive and we'll do that next and processes can be linked we're going to this this afternoon it looks like earlier it's all about building fault time applications so instead of spawning a process I can link the process to my process where if that process dies so you can end up building up this hierarchy of processes and you want to say if there's some failure I want that to cascade up and kill everybody so if I had some API service and the API was down and I was piping that to like an analytic service if both those dependent on each other having the API service die the analytic service can't do anything I might want that to spiral out and kill everybody and then try to restart it up by a supervisor and then like go down and restart everything so to show you an example of that processes that go to a spawn link that takes a function spawn link is going to link that process to my process and you can say receive if you receive the message boom I'm going to just raise boom which will kill the process so I have some process and if I send it a message boom ah I've killed it and I've killed myself but if you notice so like this error report is a Erlang error and I actually our IEX session died and if you notice we're still in our IEX session like why does it still work right we're still we're good to go because our IEX session is internally supervised by a supervisor any time it dies it gets restarted so little bit of process supervision there so the concept of let it crash is what you hear from the Erlang community and the Elixir community it goes instead of trying to rescue from errors we just let our processes crash and then we have any kind of failure and recovery logic in a supervisor yeah so raise just like Ruby it can also take a runtime error there's some different errors that you could pass I can say runtime error new here forget the semantics of runtime error but yeah you can define your own specific exceptions and then raise those and keep looking pattern match on that I won't get into that there is a rescue in Elixir so I can do a try rescue block, rescue from an error and then pattern match on the error type so if someone raised an error that I wanted to pattern match and rescue from and do some extra work that exists but beyond the level of what we're going into but raise with a string is just going to raise the runtime error like Ruby and if our mailbox is empty we're going to wait forever for a message so if I said receive, do no one's broadcasting this thing is just going to block forever and wait which kind of sucks sometimes so this thing is just until it receives a message basically just sit there and pull its mailbox so there is an after clause that you can say wait a number of seconds so I can say receive some message and then after three seconds I can say time out giving up just going to wait so you can develop semantics around receiving messages like if I was talking to an API or another process on the mesh so some other node out there there might be some latency on the network I can say go try and do this thing send a project that's peeing and then I can say immediately jump into receive loop and response back and then I can implement some kind of logic saying well if it takes more than three seconds something terrible has probably happened to that node so I can give up, crash myself do some cleanup or do whatever I need so that's what you would use after for and just realize that receive is going to be blocking forever until it receives a message question on after is that 3,000 or whatever value it might be a variable like something that you get from the big file definitely and we did the boom so that comes into like how do we actually hold state so we had to touch on processes first to hold state so let's build a counter let's say as a trivial example we want to be able to create a counter module send in a message increment send in a message decrement and be able to get the current value how do we do that in an immutable language so let's see how well live coding works here let's edit hit like a counter exs file so we can create a counter module and we can say well we need to start some process to hold some state so I can create start take some kind of initial count maybe default it to zero and what we're going to do immediately is spawn a process and then we're going to say ok listen for some messages but we want to pass in that initial count to our listen function so we want to spawn a process close over that initial count and call listen so our listen function has some current state of account whatever it currently is and what we do is we listen for messages so I can say receive I receive the message inc for increment what I need to do is I say ok I'm going to recurse on myself on my process with count plus one right oops if this doesn't click it should click momentarily I receive decrement I want to say ok listen on my count minus one and if some sender sends me the message give me your value I want to send the sender back my count and then again just recurse on myself with my unchanged count I'm done with my receive block anytime I receive a message or anytime I jump into receive I block forever until I receive a message anytime that message comes in I then always recurse on myself with my current state here it would die so one option would be outside of our receive we could hop back into listen with some current count so if I say listen count plus one here it's going to call listen I'm going to immediately hop into receive which blocks for another message that makes sense so our listen always immediately hits a receive which will block until the end of time because we have no after waiting on a message and if we throw this into IEX you can say compile that's good so I can say I have some process that's going to be countered at start and let's start it at maybe a hundred that guy's out there should be alive and should be listening so if I send a message saying hey increment hey increment again again and if I want the value from it I have to ask hey there's a message from myself give me your value again nothing happens because it sent me back a message I specifically checked my mailbox and say okay let's hop into a receive I think should be just sitting in my mailbox I've already received it let's say I receive the value and I just want to return it back to the show see it's 105 so now we have everyone understand the recursion that we're doing here we spawn a process and that thing is out there currently receiving and then recursing on itself until the end of time and that's how we hold state passes our current state in and then does a recursion and a receive I'm sorry and maybe you've covered this I just missed it about the mailbox but does the mailbox function is a key or does it filter for anything that matches one of the matching clauses in the receive and ignore anything that doesn't match so like there's a term I think I've used selective receive probably incorrectly I think there's a way deep narrowing to you can get at the current mailbox all the messages and look through them but in this case receive is going to execute as almost like a queue each time you receive a message just to go through from top to bottom does anything match these clauses otherwise no okay go through the next thing but there is a way we can actually iterate and inspect each value but normally you're going to jump into a receive and then pattern match on whatever the top of the mailbox is like first first in first in yeah so is everyone clear on this the caveat is we don't write too much code like this directly because this is where it comes in and there's conventions on top of this to not have to do this and I wanted to write a manual version first just to give you an idea of how state is held it's all through processes so this process could be holding something more than a count but the idea is we have these things are cheap we spin them up they're almost their own actors out there and then we like query them with messages it's all done with message passing so what you see typically is you would write a client like we call this a server I didn't want to hurt a gen server I'm going to try to tie these concepts together we can almost call our counter like a server we're going to send it messages and we get messages back so we can write a client that queries our counter server sends it messages and we can make a nice API on top of this I think I have an example written out here I could write a counter dot client module and do a nicer API so we wouldn't have to jump into our own receipts to check everything every time so I could wrap an API around this and say increment, decrement, that does my message sending so anytime you're sending a message in your elixir code you almost always want to abstract it because the caller doesn't care the caller wants to perform an action and get a value back so I could say increment, decrement give it a process ID and that would just send a message do whatever it needs to do to increment or decrement and then I could make a counter dot client dot val get the current value of that pit and that's going to send that process a message and then immediately jump into a receipt to get the value back and what this lets us do is just make a nice API on top of all this stuff I paste all that in I have a just start the counter server starts and then my client can then clear that server and say hey I didn't sort the pit so I have a process of my new counter server and I can say counter client increment give it that process ID so I should end up with like what 3 so now I can say counter client dot value give me the value of that process I get 3 yeah so v-1 is going to give you the value returned negative 1 is sending you the last thing negative 10 would give me the things we have so it's just a nice way to get the last value okay I don't know what that means I don't know why it's going to be a 20 so ok is a common returning the atom ok is very common in Erlang and Elixir so it's not unusual to see ok I don't know why a positive value I don't know what a positive value would have represented well it's probably the response to the comp that has the number in it the response to 20 was 3 so if you do v of 20 use negative values to look up the expression values relative to the current one so you're saying positive is what well if you see the return value well it has a number in it 20 well of course oh that's awesome cool there's something new send me a pull request like getting started documentation I don't even have v documented so if you want to send a pull request this afternoon that would be awesome minus one would be the other previous value zero would be the current thing I don't think it would so that's holding state and then we would almost always abstract it so a lot of times once we get into OTP you're not going to be doing this kind of stuff yourself but you will be sending messages using the send and receive occasionally and you would almost always want to abstract that it's almost like the internal details just like standard object-oriented patterns that we write the caller doesn't care what the message syntax is it just wants you to do some work and then we can register processes under a name so if I wanted to say that that counter is going to be named count I could then register that we should be able to do that here so I could say process register give it a process ID and we're going to name it counter so now we've registered that process and people can send counter messages directly and I can ask where is that process to see if it exists oops really oh I have to give it the name so if I wanted to then send it a message later I could say hey give me a thing named counter and it's going to return me that PID so it's a way to store messages or to store a process and we could do this globally on a mesh again there's a global register the process on the current node but if we had like 30 laptops connected all together right now I could globally register register name a process which will actually do momentarily when we run the twitter aggregator that will say anyone can register a process globally on the mesh then you could look up my process ID of my laptop to send messages to mesh would be if we connected Erling and Elixir nodes together and then if I send that PID a message it could be running on your computer so a message just much nodes connected which we're going to try to do right now so do we still have internet anyone know it would be awesome if we did okay so if we have IEX up and running CD into the or OTP directory OTP source tweet aggregator this is a OTP application OTP stands for open telecom platform which is a great name right so OTP started from Ericsson at a telecom library it's maintained its name but you can think of it you can think of it as Erling standard library for conventions for writing distributed fault tolerant highly concurrent applications so it's a set of conventions defined around that manual process state holding that we just wrote and we went through spawn and spawn link earlier so it's a set of conventions around links processes and if they die you run them and monitor them with supervisors so it's doing all these things it's almost like I've heard it termed the rails of concurrency and that's the best way to think about it so there are these processes that we can monitor we can link we can crash it's a set of conventions around everyone had 20 different ways to do it so finally Ericsson was like let's put a library together to set some same conventions around how most people write these things but it's called open telecom platform which is trips people up initially so if you're within that directory and you have internet run mix steps.git and for you it will probably do more than that but hopefully that works for everyone mix if the OTP source tweet aggregator so Lixar Express OTP source tweet aggregator oh I did clone the repo I think I may miss a step wait I did clone the repo and it just gives me runtime error undefined function dex one second so Lixar Express you should be able to clone that and we're going to try to run a Lixar application but run it across everyone's computer screen time what's that the URL so chris mccourt clone that to your local machine clone it just in like bash and clone it as just to get repo and if you have it cloned cd into the OTP tweet aggregator directory so you have this cloned in your internet directory mix depths.git should pull in the dependencies for this project not an IEX not an IEX problem that's probably why I tripped that's probably why we're not the error so yeah outside of IEX in bash mix is a build tool that ships with a Lixar you can almost think of it like bundler and gem and rake combined so it runs you can do like mix tasks similar to rake tasks in your project mix is also like bundler where I can fetch dependencies, specify dependencies mix depths.git that will fetch the dependencies and mix compilers for projects so it's like a huge build tool and you can also say mix new and it would create a project OTP hierarchy with like standard test directories so it's almost like rails new so it's a really awesome build tool that combines a lot of great ideas into one so does everyone at least have that cloned and who was able to run mix depths.git successfully well it's running we'll let it run for a second so what we should be able to do if it finishes does anyone have it actually up and running like it's done, mix depths.git is finished ok so if you go into the documentation online on the OTP directory source, tweet aggregator there's a readme and we're going to try to we're going to see if the standard Erling port is open and we're going to connect up our computers together and run this program on a mesh so to give you an idea of what it does I'll run it on my laptop first so I wrote this and I wrote it into a single machine and just assumed it should work on 30 plus and it did so it was my first time writing like a distributed program and I put this together and I'll run it on my machine internally so the goal of the tweet aggregator is I have a projector that I want to send some tweets to and all of you guys are going to for me, make the request to Twitter and then when you get messages back for whatever keyword that you want to search Twitter for you want to send a message to the projector node and display on the projector and I didn't want to have all of you have my OAuth credentials so I didn't want to have to distribute those so I have another node that I'm going to call the gatekeeper that runs on my laptop that you can send a message saying hey give me Chris's twitter OAuth credentials and we'll send you a message back so here they are so I don't actually have to distribute those to you manually on a thumb drive or copy paste so there's three elements here the gatekeeper you're going to send messages to saying hey give me OAuth credentials so I can make a twitter authorized search and if I get any messages back for whatever keyword I want to search I want to send that to the projector node that's displaying all the results so we're doing distributed programming and I can run that all on a single computer to show you that it does work so I'm in my tweet aggregator directory I have some you're not going to run this I have an ignored ENV file that has my twitter credentials that I want to source so I can make authorized requests and I'm going to check my IP first for some reason you usually can use post names but we haven't had good luck with it in the past so I'll have to use my actual IP address fully qualified name depending on how the network is configured we'll see if this works so I'm going to start up an IEX node that runs on my mixed dependencies but I'm going to give it my fully qualified name so I'm going to call this node gatekeeper at my IP address and the cookie nodes run with a cookie which is really a password so no one can connect on this mesh without the password which I named foo here the only caveat is everyone needs to be good citizens here if we're connected together you could execute code on my laptop to do anything I would not be very happy so don't do that but this is going to just run a node on my laptop with the name gatekeeper and smx is going to say hey run this as a mixed project so instead of running IEX it's almost like rails console brings in all your project dependencies just tweet aggregator project with all its dependencies in IEX now I'm in IEX like you would expect but I have access to my tweet aggregator project namespace so I'm going to start the gatekeeper as a module I've defined I'll go through the code after we get this going gatekeeper has a become leader function that basically is going to globally register a process named gatekeeper on the mesh I'm going to create a PID but name this on the mesh gatekeeper so other people can look me up so it returned yes that's what Erlang does when you globally register so I should be able to say global where is name gatekeeper ooh what did I name it it's somewhere on the mesh I guarantee it oh gate underscore keeper so become leader is going to spawn a listen like we saw earlier I wrote this without OTP but we're going to say have I globally registered gatekeeper and I get a PID back okay that worked so now I'm going to create a new bash tab but this could be on any computer so what you're going to do if you get this working I'm going to start another node named aggregator you're not going to run the aggregator I'm going to be the only aggregator and that's going to run the project dependencies but I'm going to name it aggregator that's my IP address so who has this code all the dependencies working awesome so the goal of this is you're going to run oops if you have to read me up you're going to run a command just like this but instead of client one you're going to do like first initial last name at your IP address so your IP address has to be correct and it can be anything so we don't get clashes do first initial last name ifconfig should give you your IP address if you ifconfig you should be able to get your current wifi IP address depending on how their networks configure we may have to switch the port that Erlang's operating on I'm going to try to do the default but we had this running at Panera one day over their wifi on port 80 but it all worked so from my gatekeeper that I started I'm going to try to connect to it so I can say node.connect and I can give it a fully qualified name here so from my yep it's a problem only some people have successfully done it it's the network okay try again okay awesome oh my gosh someone already joined that's amazing distributed programming so the cool thing is on all your machines you just joined one of these nodes do you join the aggregator or the gatekeeper okay so do a node.list yeah couple in node.list you should get me which is one node okay so watch this so you've joined me I've joined you the gatekeeper node which is just hanging out by itself watch what happens when I say node connect here so I'm going to connect up from my aggregator which you're connected to let's surround this in quotes did you get a message saying that gatekeeper joined so do a node.list again so if you join a single person on a mesh you join everyone so by joining a single person the mesh is distributed out so you're connected to everybody now just pretty awesome so there's no extra fanfare you're connected to everyone together you connect one person you're connected to everyone so now what's up sorry I didn't think someone was going to connect so quick so you want to start a client node here so you're going to run IEX this whole command here you can copy and paste it but do instead of client one do first initial last name at your fully qualified IP address with the cookie foo and dash s capital s mix ruby central that's probably did you just run mix steps again yeah I think that's just the wifi filling out and then you're going to node connect instead of aggregator 127.001 it's going to have to be node connect aggregator at this IP address here and we'll wait until a few people get on this is awesome I was worried that we wouldn't have wifi mix steps I guess when you run any of the IEX commands oh computers cool so we so I have a node monitor process that's actually just looking into joint events that's going to print out everyone's console so now I want someone to send my gatekeeper message so you should be able to say oops and your shell you should be able to say tweet aggregator gatekeeper got access token oh should be able to get an access token here hold on that's a problem it's my gatekeeper online here I'm confused on which tab I'm in just try again some people have had issues with that for some reason my gatekeeper is not providing its access token I may not have sourced I got to quit out what's that but you need the gatekeeper access tokens first I may not have connected him properly no no we're not even hitting it yet but we will and we will hit a rate limit pretty quickly it should be fine no one has tried to become leader on that gatekeeper right don't do that you may have had like a net split with a wife I only have one person yeah second I saw that you left yeah what it's probably the wifi being problematic yeah I should have rejoined let me try one more time you should see gatekeeper join here hopefully is a gatekeeper join anybody everyone left but me but you're still up and running can you try to quit that yeah I think I try to be run there could be wifi is probably falling over but hopefully we'll get something at least some messages going yeah just try to be run no connect again on you should be able to means I'm rejecting you for some reason yeah okay new plan put out of your session and we're going to run on port 80 it could be we're trying to run on the default a great report should be a epmd port 80 and then this is basically go to tell the Erling to send messages over port 80 instead of its default run that from the shell and it should just return you back to double dash single dash we need to undo that if you were trying to play at home when you restart it would be back on default but it's not going to hurt anything so now we should be running on port 80 let's try to see what happens when we start back up all of our nodes the connection should be identical to what you type before yeah so try to node got connect on the aggregator again I'm going to connect to that real quick over here um it's fine yeah 1386683 is that right yes um I mean I'm able to join myself but that's because it's my own laptop everyone's just getting false let's try RailsConf Expo Hall what happened we can leave it on port 80 it should be fine yeah it's going to change though so but the uh couldn't connect to the Expo Hall maybe I have no internet but I should have an IP quit out if you had those shells running you had to restart them after the EPMD command uh let's see what happens here with this IP address so the new aggregator should be uh this guy so are we on Expo Hall Expo Hall it's the only Wi-Fi access point I even see right now uh port 80 so like if you run that EPMD command it should return you to standard out and it should just be set now are you running in IEX or in your shell yeah sorry I think sorry which way oh uh RailsConf Expo Hall it was working before so um so the whole point is normally it just works so if you have a reliable network let's try for a little longer to see if we can get it working the whole idea is I can globally register a process gatekeeper or the aggregator and then when you say send PID boom or foobar it literally will send it to anyone on the mesh and there's no extra fanfare there's no extra code to say hey call that machine over there instead of my own laptop it's identical so the code you write to run on one machine you write to run on the entire mesh it's going to broadcast a single process ID um if you wanted to do something like that there's a building thing called process groups where I could say all these processes can join a process group and any message sent to that process group is sent to all processes it's like a pub sub type thing and that's supported in the standard Erlang standard library like this is the machine to see that but go oh I don't want that process anymore no it's just for this to my PID I mean if you were doing like uh you were trying to sample promiscuous mode on the ethernet you might get it it will only go to a specific mailbox of that node on the wi-fi we could try let's try Ruby was central one more time since it was working momentarily even though we couldn't send any messages let's try Ruby was central once and then uh I could walk through the code but the idea is normally you would just you would pull twitter you would ask my laptop for its credentials then you would pull twitter get results and then send the aggregator a message to display on the console over on the projector I think at least me the same one I'm back quick let me start with the gatekeeper up because that guy is needed for everything and make sure you have to use quotes so if you're trying to connect doing a node connect make sure you give it an atom but use quotes on the atom I want to make sure it's not accidentally forgetting that this is a good sign though so when you say node connect you give it an atom but you give quotes after the atom so make sure you provide that you yeah I think so normally someone after I become leader I'm trying to become leader but it's hanging because the global process registry is synchronized across all nodes so the wifi is really horrible so it's still waiting normally this is instant but saying globally registering a process it's actually going to lock the mesh and ensure that only one person at one time can globally register a process and that's handled automatically that's freaking out right now I'm going to blame the wifi I'm still trying to become leader come on and uh okay am I leader so can someone say tweet aggregator gatekeeper access token yes if that works for you you've sent me a message and there's my private twitter access token but see if you can recreate this you should get a random string yes okay so internet programming okay so that's pretty cool right you sent my laptop a message I'm writing a note for just a gatekeeper I sent you back the access token pretty cool so now you should be able to pull the twitter api so say tweet aggregator this is going to be really verbose because I'm not aliasing it uh dot search clients dot pull and then give it an array of strings like uh I'm going to search for elixir and it's pulling twitter and then my aggregator is going every 10 seconds your note is going to pull twitter and send should send this projector a message of the results we'll see what happens uh so let me bring that command back up tweet aggregator search dot client dot pull and then give it an array a list of strings it could be anything so search for something that you want to search on like Justin Bieber is what I use a lot for testing because he constantly had new tweets so so every 10 seconds it's pulling and eventually it's going to exhaust my rate limit uh but we should see this is my aggregator right why am I not oh my aggregator needed to become leader so you're pulling you're notifying me but no one became leader of the aggregator it's the last step this works we should be getting uh messages here come on so normally this is, this should be instant I think the wifi's the week that um block everyone's machines to make sure the process registry wasn't um overwritten by anybody but like all this stuff is handled for you where you can globally register stuff on the mesh and you don't have to worry about someone else trying also to become aggregator at the same time if you did your process would actually die so say you were running this in some kind of production what kind of steps would you what tools would you use to try and I mean it seems like well some of these calls are coming back pretty slowly but is there any way to find out why and what's going on yeah so there are are tooling that I don't have much experience for that but there's like a conqueror's new tool that came out recently oh my gosh it's working, Scott, somebody Ryan K, okay distributed programming so yeah there are tools for debugging these things I don't have experience with them um but you it opens up a new set of problems of programming and if there was like a net split for example now you have a mesh that like half of the people are connected to half the people and it's like who's alive and who's not alive so you have to handle these unusual scenarios where normally you wouldn't have to handle it but the coolest thing for this like I said if we have time I don't know what time it is we can go through this code and I wrote this using the OTP framework built into Erlang but writing Elixir code I wrote it on my laptop just sitting on my couch and I just globally distributed these things but I hadn't actually tried it so I wrote it against one machine I ran new tabs to run new nodes on my own laptop that worked and I was like well from what I've read this should just work on everyone's laptop and now we're running how are we in no-dot lists work there was no extra, no extra code is written how many people do we have connected so we have 21 people running this program on a mesh right now and literally it was the same code single computer so that's like the dream I saw people we're getting some crashes here you may have hit the API rate limit so these are the Erlang error messages which Elixir is trying to improve and they're printed in Erlang's own terms which is a terrible idea so you get Erlang error messages in like a data structure instead of nicely pretty printed yeah so Elixir already has a really nice error message layer but like since we're hooking into OTP here they aren't we haven't yet wrapped OTP error messages so you still get some Erlang error messages you can obtain a taste for Erlang error messages and actually get meaningful data out of them but for me it was very difficult getting stuff like this at first so there is meaningful error message data there it's just embedded in a data structure so I don't want to knock this stuff too much yeah so that's still working ish so that's OTP we can hop into some of the code while this runs but basically your clients are just going to pull forever if someone wants to play with this I'm going to kill the aggregator node you should see it leave you should still stay connected to everyone else so aggregators gone someone I'd say you want to end here yeah you had good connection earlier can you do tweet aggregator dot aggregator dot become leader like tweet aggregator dot capital A aggregator dot become underscore leader and you'll globally register yourself as the tweet aggregator and you should actually start seeing everyone's messages go to your laptop instead of aggregator dot aggregator we should have just to alias that we could have just typed alias in the shell we don't have to specifically do that so where are we I can wait no way I'm going to type that test for you oh so you're are you getting any messages so I think some of those may be either a failure to fetch API issue are you getting any actual tweets we may have hit the rate limit I don't have any other credentials to Nika last time I did this I had a couple twitter accounts I just like swapped out the gatekeeper to use different credentials but you're just getting failure messages so the cool thing is like anyone can hop on like for this example you had your own twitter API credentials you can source those I could kill my gatekeeper since I have maximized API rate limit someone could then say hey I'm going to become the gatekeeper and you can lease out your credentials and then all those clients every time they make a request they're just asking the gatekeeper every single request to give me your credentials so it would just work so it's the whole thing like the fault tolerance this is not a great example for like a beginner scenario we could have we could have each node say if the gatekeeper or the aggregator for some reason becomes unavailable automatically just become the leader and you would globally register yourself as that and early OTP would actually the personal machine would ensure that the mesh only allowed one person to do that so you could have a mechanism say hey become gatekeeper if the gatekeeper fails and like then you know fault tolerance so as long as the gatekeeper is alive it would work all the nodes use like their own yeah you could have each node user on twitter credentials I didn't the easiest way was for me just to be able to give those out but I didn't want to have everyone just like type them in so it actually worked out really well to make a node be the gatekeeper just to kind of show off this like message passing stuff so if we pull the gatekeeper up normally you would write this in what's called a gen server in OTPs it's a framework but I wrote it in just a bi-manual just manual elixir just to show off that like how you would do it it's very similar to like a counter example but here's the documentation on everyone over that I can say app module doc and then give it a string and this is what if I said h tweet aggregator.gatekeeper I would get that pretty printed markdown in the console so I can provide module documentation I can get that with the h helper and my gatekeeper is just like I say become leader so to say hey the early global on the home mesh register the gatekeeper name and it's going to be this pit of a listener and then listen is very similar to what we wrote for our like counter where we just basically wait for some sender to ask us for an environment variable and we kind of protect it from you guys trying to ask for like I don't know if I had some like secret environment variable on my laptop it restricts it to who asked about the constant earlier are they still here okay well you missed alright so if I say at ENVVAR in my module this is called a module attribute and module attributes it's like don't be fooled by the outside it's not a really like an attribute accessor it's almost like a constant so module attributes almost synonymous with what we do with constants in Ruby but if I define some ENVVARs it's just a list of atoms I can then reference that anywhere in my code with just at ENVVARs so it's a way that you would use constants in Elixir and I basically just recurse on listen forever and then anytime anyone asks for like the access token I just expose this like I have like the client server written in a single module so if you ask for the access token I basically call git which is just a function that takes whatever environment variable you have and this is like the send receive loop that we saw earlier so ultimately when you say hey gatekeeper give me your access token it's going to say okay send whoever the leader is which is going to be me in this case the message whatever environment variable you want and then you immediately hop into a receive loop to receive whatever you expected back and I don't have an after here and this is where I probably because it will block forever so this is where we were talking about like fault tolerance you would do this in a different way if you were writing a real system but for fault tolerance in this case I could literally say okay well after I try for 5 seconds to get that value gatekeeper's got to be gone so then literally I could say become leader so there's fault tolerance so after 5 seconds I'm trying to get and I'm going to call become leader and then I'll become the leader and then anyone else that asks the gatekeeper or an access token now is asking me which is pretty cool two nodes both try to become leader at the same time so if you saw when I tried to become leader both times of the aggregator and the gatekeeper it took forever it blocked my accession for like 10 seconds so it will lock the whole mesh everyone's machines and only allow a single person to globally register that name I mean like for the fault tolerance so you have 10 machines two of them at the same time one of them locks and is becoming leader but the other one also hits the after it just won't become leader it would try to become leader and then whatever error message we got before if I try to become the aggregator it's going to die and say already registered let's see I have a okay so it should if you tried to register it would crash your process whatever you're in hopefully your supervisor would restart you it would ensure it would ensure consistency that makes sense you'd have to rely on supervisors yeah so everything like your clients right now this app is pretty big but all your clients are currently supervised you saw those error messages popping up it was just polar dying but it was restarted and it kept trying that's because we have a where is it I go into OTP so I have a search supervisor and a lot of this is kind of like mundane Erlang OTP stuff which is like there's whole books on it which you should read if you're really getting into this but I can create a supervisor for my search server that's going to basically pull a twitter API and I can start a worker with the term that they use saying I have this gen server which is going to be a thing that we can query for values that recurses on itself wrapped in like a convention and I can say if any of those workers dies there's only a single one I want to like one for one there's always different options one for one says if a worker dies I just want to restart it but let's say if I had a bunch of pollers going I had like an analytic service with different APIs if one of those failed to hit Facebook and Twitter let's say if one of them failed I want to restart all my workers for some reason and that's a bad example but you could say one for one you could say one for all and the supervisor would say if any of my things I'm supervising dies just kill everybody and restart everybody so you can have different restart strategies so if you have like all these workers depending on themselves and one dies and there's like a ton of different options there's options to say if a worker dies try to restart it but wait three seconds and then try to do that like ten times and if that fails and then kill yourself and then your supervisor would then be notified so you supervise supervisors and that would go all the way up to the application supervisor and if that guy died that's a problem but basically you develop your OTP application that's a hierarchy of supervision trees and it's just really a unique way to think about programming and for me I see it as the future of the way I'm going to write programs it's a totally different way to think about the supervision programming like for our Rails apps we kind of like sew out maybe we make some REST APIs or we communicate over like a Redis bus but we don't think about ever connecting multiple apps together in this manner it's always like we have to put a wall between them it's a unique way to connect these things but for the OTP land you develop different projects you can still like sew out like service-oriented architecture but you can have those things all connected on a network together calling just native Elixir back and forth and you still develop clients like the term client server is still a concept but it's not the way that we would think of them as Rails developers it's the conceptual thing of I'm going to send this server a message and I'm going to get a response back and it's all in native Elixir code really interesting and I see it as the future of the programming in my opinion Ruby could learn a lot from this but I think we are limited by just the semantics of the language so for me my goal is to eventually write Elixir professionally yeah so I don't know what it's using back and forth I'm assuming it's efficient all this was written around telecom infrastructure initially so if you think back in 1986 is when they first developed this all these semantics were in place in the 80s which is kind of crazy even today any mainstream language does not have these semantics so back then stuff was a lot more expensive than it is today hardware-wise as far as doing anything computation-expensive so I'm assuming it's efficient but I don't know the semantics of how it's doing it yeah seems like we're through the demo should you do like an I.O. or talk to a database with Elixir like if you wanted to pick up a process you know you're working in your Rails app and you want to put something on the queue or have Elixir work on certain pieces of it integrated with your existence yeah so Ecto this may answer your question is anyone familiar with link from .NET okay I've never used it so like link is a database like access language to .NET and Jose and another core maintainer of Elixir put together Ecto which is basically using macros to write like a database access layer so you end up with things like I can say I can create like a queryable I can define like fields that my database maps to I have a city field, it's going to be an integer or a template integer it's like a DSL so I can say like from W and weather where the precipitation is greater than zero so I write in Elixir code a query and this is a macro that's going to actually perform a query for me so it's almost like synonymous with like a link type scenario but literally this is just Elixir code and it's using a macro that from is a macro to take in the AST of W and weather where select W and work that into a SQL query so this is one option that you could hook into a database access layer internally they're running a connection pool you may have been asking more granular maybe I mean that's fine I don't know where they you know how you set it up I mean this is this almost feels like an abstraction like active record okay so I can show you off I'll show this off a little bit so I wanted to show Ecto first because I see it as the future but I put together Atlas which may look familiar to you it's a database access layer possibly inspired by active record possibly so I can say def module user now use is something we didn't go into it's a way to invoke a macro on Atlas model that does some code generation and then I get these macros like field so that I wrote this as my first like query into metaprogramming like field, ID integer, email string and then some familiar validations and so I've shipped this works but I'm not running it in production and I've started a web framework called Phoenix that I want to replace my Rails development with long term that's my main focus but I would love contributors on this but you can do crazy things like you know I can say validate format of email I can give it a regular expression just like we would expect in Rails and I can create scopes so the way you would call this with a pipeline operator is like this so I can say user where, email whatever and that would return me some kind of query state so all of these where I have a where that is a single airdy of a keyword list and all the ones I'm piping into I also define a where that takes a first argument of the current scope so then I can create queries similar to Rails instead of chaining where I can say email userexample.com type that into user where state is not null and then instead of querying that off user I'm using the repo concept like Ecto is and saying we can have multiple repositories in our app that connect to different databases so I can query out construct this query and then I maybe have some user repository right here that's connected to a user database that I have defined in repo and then repo actually is going to perform the query that makes any sense so this is my experimentation with the database access layer but hopefully maybe to inspire you that we can still do very Rails like things in Elixir in very similar manners. Has support for similar databases? Yeah so this is Ecto is just post-cust right now there's a pull request for MySQL but since Elixir has had some better changes recently there's some work to get that in place. Atlas is just post-crest right now as well but I'm using protocols which I forgot to cover protocols is the polymorphic layer and you can also use behaviors which we wouldn't get into behaviors are almost like specifying the interface so I've made Atlas in a way that you could define your own MySQL database driver and plug it into Atlas and you only have to implement like 10 functions as long as it was connected to MySQL and could perform a query to access later. So both Ecto and Atlas the goal would be to add multiple database drivers but it's just post-crest right now you want to get your hands really dirty and so you can do awesome stuff like queers would be composable so I can say define a scope as like where the site is admin and if you pass an email to this user search I can then rebind that scope and keep building it out so that's Atlas and then I want to show a Phoenix for a second because this is my long, long-term goal is a web framework that gives me all the productivity of Rails I don't want to recreate Rails because a lot of the concepts don't necessarily map over to a functional language but I want, so the dream is a framework that makes me as productive as I am in Rails with similar conventions but that I can run on the distributed mesh so 50 computers to really like conquer concurrency and be able to like sew out my app as different OTP applications but all still running on the same mesh together so you can do cool stuff like I can say get the pages page just like you would do in Rails and it's going to generate some route helpers for me saying like as page here then in my controller I can say like redirect to a page path of that router pass in a keyword list so I'm trying to develop things that are kind of inspired by Rails but I'm not just trying to recreate Rails I'm trying to build on top use some like a lot of people like to hit on Rails especially from the early on community when they see stuff like this but Rails gets a ton right and makes me happy to program it so I think that we've had 10 years of innovation and 10 years of people going back and forth on these conventions so I think they should be reused so I'm not trying to recreate Rails but there's some undeniably good things and we should borrow them so this is really young but it's progressing steadily I have a web socket layer on top as well so what started me into Elixir originally was I got in anyone heard of the gym sync by chance real-time Rails partials so I wrote sync a year ago maybe and I was trying to do web sockets in Ruby and eventually I was able to do it through Faye I tried to get it in place through just vanilla Rails and action controller live anyone familiar with action controller live and there's no concurrency store when it comes to Rails trying to open connections and keep them open so I heard sync and it works really well but it opened my eyes to how are other languages doing this and then I heard of WhatsApp at the time running a million connections per server and I was like that's pretty awesome I want to run a million connections per server on my Rails app and that's what I got interested into Elixir and just to show off I have a PubSub layer in Phoenix where like you have a some issues so it wouldn't be awesome on your Rails router you could just say you have a router and then you have your routes I could say in Phoenix now channel give it a rooms channel and I define a channel in Phoenix to respond to some PubSub messages so I can handle joining from different connections and I can handle events you're familiar with like Socket.io and Node it's very similar I can handle event new message and I can broadcast to that socket all the all the listeners that same message and then I have a JavaScript layer which is like this is a trivial example I'm requesting feedback this isn't an emergency master yet it's very close but the code we've seen live screwed down as an entire chat app so there's a small JavaScript layer where I can say you know Phoenix Socket and then I can say hey Socket join the channel rooms and then like a topic lobby and that topic could be like a user ID or anything to scope a like PubSub broadcast to and then I can say like Channel Send so I can broadcast on that channel new message and I can also listen for new messages and then run some kind of callback so this is where I'm at with Phoenix currently and it's super young I'm not going to replace Rails immediately and I love Rails so I don't think Rails is obviated quite yet but I think that the building real-time applications in Rails is not a fully written story yet I think that as a community we need to focus more on providing mechanisms to do that and I think Elixir is also a great fit for building out like a bunch of cloud buzzwords so I think it's perfectly suited for like high and current high fault horrible distributed web applications and hopefully I've proofed some of that today but if you want to play with anything now I don't know how I'm doing time-wise but I'm welcome to answer any questions and anything we haven't seen we skip protocols but they're in the docs I think we'll be on that with OTP but if anyone has any any input or anything they'd like to see so today there are Rails developers in the box like what are some of the differences in lieu of something like the in-question yes so my so there's a couple options and I'd love to have collaborators so my goal my secret to get it in on like actual client work would be to write a sidekick compatible worker processor as something that would actually be a real-world use case so we had I worked on an app that was doing like social analytics hitting a bunch of different APIs and we were doing it all on Ruby we didn't try like a met machine or sell you the way out so we were running we wanted to make a request for Twitter to Facebook LinkedIn we would run a web request and we would block that worker but it basically got incredibly expensive like on Heroku we would have to run massive amount of workers and it would be like we would block other users so a bunch of people at the site at the same time we would max out our workers and someone may have to wait a minute until their API request came through because we were blocking an entire Rails process like 200 megs of memory just to wait on an API request so my idea to get it in place in the production soon my goal is this year would be able to write a sidekick compatible worker because we use sidekick and it's awesome we'd probably make it work with RESTU as well because sidekick is RESTU compatible but the goal is maybe we could do a perform async on sidekick onto a queue that an elixir process would be watching an elixir process could pick that up do some work make the API request it's almost like data in, data out the Rails app can maybe provide the credentials down all the data needed to perform API requests it makes the API request incredibly efficiently because we can run processes and spin up a million of them we could run a million API requests but then when you were done with the data on the elixir side you would enqueue a job back on the Rails queue side and it would pick it up like any other regular worker does that make any sense? so I have some ideas that some like I have a ton of fine coding in elixir so it's not just the infatuation I think there are some clear use cases that I've hit in the real world that it would be a perfect use case for to like sideline against all the awesome Rails stuff that gives us so I think like it would be years before I would be able to replace my Rails development but I think in the meantime there are some clear wins doing like anything web socket related like that's why I have web socket in Phoenix so quick like there's no view layer currently so I hit web sockets first before the view layer because I have a project coming up that's going to be doing some like real time updates some like user has like a feed of activity we want to be able to update that in real time so we're coding the project in Rails but if I can get Phoenix in place stable enough we're going to have offload that pub sub to Phoenix so you create a Phoenix channel that ran alongside your Rails app you would write your javascript doing like phoenixchannel.new and all the authorization on elixir side yeah that's what I got into yeah those are my thoughts so I work on Rails full time so I'm thinking constantly about how to get this into production in a responsible way in a way that makes sense and I think offloading pub sub anything like really heavily blocking I.O would make sense how do you start the socket? not yet so it's like between a web framework an active I.O. I.O. I.O. a web framework an active record replacement I haven't quite found the time but that's what that's what I'd like to do so it's on my bucket list yeah so I don't have actual professional experience with that but the way that works is each module has a version and that version you would do a release of your software and you would have a call back in the module to say there was a code change and if the version changed you could say what was your current state on a gen server so if our counter example is a trivial example but if we want to update that counter that process is running and we have to kill that process to restart and run the new module code so how do we do that with our current state so you would do a release with the new module version and then you would write a function a code change function that said here's the current state and maybe that counter now is going to be a couple of the current count plus the number of requests that have come in totally and you could actually take the current state and transition the existing state to the new state required by the code change and then it would restart that process with a new state with a new code that makes sense I don't have a 10 experience with that and there's a I would caution people code reloading is awesome and I sell that as like that's why Elixir is great and Erlang is great but for a lot of real world systems unless you truly truly need like hot code swapping a lot of times it's way better to just you know on our Rails apps we'll do like a unicorn deploy where we wait till the process gracefully dies there's no like reals to spend up time it'll wait till the rail spins up completely before serving new requests so there's no latency in pushing out code I almost always recommend that as the first step because the problem with hot code swapping is unless you have a system that truly should never fail you still have to write code around a node goes down, what if there's a net split you still have failure scenarios where hot code swapping still isn't going to save you you still have to write code against stuff crashing having to be completely restarted anyway someone trips up our power board in the data center how do we handle that so you still have failure scenarios where hot code swapping isn't going to save you so if you have failure scenarios that's handling code going down you might want to use that for just graceful restarts versus all the complexity of hot code swapping but it's still awesome so if you want to look into it it's very cool question what's the testing experience like it seems like language like this eliminates old classes yeah so like having no like shared mutable state is awesome and there's testing tools built into MIX so in this my Phoenix projects MIX tests is going to look in the test directory and run with tests in your projects super fast if we open that up let's see if I go into so testing it's almost very similar to uh Ruby's test unit so I have a test macro I can give it a description and then I do in block of code and then everything becomes everything is just an assert because we're able to get at the representation of code I guess I'm trying so as far as like less things to test for I found that interropping libraries is incredibly easy because there's no, nothing's being mutated it's like someone, there's a web framework called Dynamo that Jose started but it has since handed that off to someone else and someone, there's a view layer in Dynamo the web framework and someone was like can we get this into Phoenix so like that'd be great but like I can't imagine we haven't looked, we haven't tried to do any interop with this framework it's probably going to be impossible and there was a poor request that evening of like massive code that they just copy and pasted and it just works but because you have these cases like functional programming becomes like data in, data out so I feel like I've only been doing this for a year compared to object orientation but there's less it feels like there's less dependencies because there's less to clobber and not be aware of so like the debugging becomes how is my data being transformed incorrectly versus what's the state in these hundred different objects so I feel like things are easier to test and easier to debug but I don't know if that is just because of functional programming or if Elixir provides us some kind of extra benefit but yeah the testing is very just asserts, just kind of cool and you get nice error messages so check out Phoenix, I have a couple resources, if you want to get into this there's Elixirling.org has a new getting started section that just shipped like last week two weeks ago, which is really good FreeNode, Elixirling IRC I live in there constantly, I always tell people I'm worried about being too active so I'm always willing to help there's actually a lot of helpful folks in there, Joseph he's out in there and he'll answer your questions so that's IRC is perfect don't be afraid to ask beginner questions, like the language is so new that everyone's a beginner and we can all learn from each other so hop on there, that's probably the best single best resource is just IRC watching the discussions asking your own questions github.com, Phoenix Framework is where Phoenix lives, I love ideas trying to discover some new ideas and bring some awesome innovation from Rails into Phoenix where it makes sense, so if you have any input on that hop in on the issues list I'm kind of using it as like an active discussion for other issues with like RFC requests for comment and I'd love to have collaborators, contributors I'm Chris McCord on Twitter and it's my email if you need to reach me I'm always willing to help out and I'll probably be hanging around a little bit afterwards if you want to see any other code examples but the Prague Prague book, I don't think I have that listed there, oh it's I wonder if they play in there really, yeah so the Prague book by Dave Thomas is where I started and it's excellent it's like a condensed version so like he wrote like pickaxe book anyone has a pickaxe book so it's not built as like a complete exhaustive elixir book but it's enough to get in and get your feet wet it introduces OTP a little bit and we'll talk about like enough to get you started into not knowing Erling and then I finish the book with enough knowledge to be able to find out whatever I needed so like you'll come in and if there's some Erling documentation you need to get into you'll at least be able to be proficient in reading it, like how to do things cool, I think that's all I have thanks a lot