 Good morning Okay, I want to start Just by saying thank you because so Jim freeze. I don't know how many Concerts I've been in a new organize a lot he is tireless and taking a risk and organizing yet one more brand new one with a new group of people and You know a whole series of challenges. I'm just really impressed And as you'll find out he runs a great conference. He has a lot of Detail that is really really nice. So I just want to say thank you to Jim for organizing this So this is Steve jobs. He actually fought to have it think different. I can't stand that. It's got to be Please Listen the publisher Okay, so I think that if you don't Keep reviewing your thinking. Well, there's a story in business that if you're not growing your dime I think it's the same mentally. I think if you're not growing mentally if you're not thinking use things If you're not challenging yourself, then basically you're stagnating your dying in your head So I think it's a kind of a duty to keep challenging ourselves to keep trying to find new ways to do things in my own career I've been through a number of transitions. I'm gonna start off my first program. I used to be basic And I really really enjoyed that. I Went to some early old languages. I did all sorts of stuff. I keep changing paradigms as it goes along But at the same time I have been doing all the development of various kinds. How many people here are Younger than 40 years old. I hate every single person Because I've been doing all the development before you were born And You know what? I got into a little rock because it was like easy to do after a while you learn it and it becomes Instinctual it becomes passive and that's how you that's how you go and One of the things that I Really love about this last 18 months has been that Elixir has changed the way I think about programming Not just in terms of life. It's a functional language. It's actually changed my conception of what it means to program now the problem is I would love to explain that to you I'm gonna try to explain that to you But it's not easy because it's kind of like how I think about stuff and Lord knows how I think about stuff is weird So I'm gonna do my best to explain it to you However, what I'm not trying to do is to sell you on my way of thinking that's not what I'm doing at all Instead what I want to do is just to show you an example of a way in which the language and the environment Have a profound difference on how you think about what you do All right, so wish you luck That point goes to say good luck Dave Okay, all right, so Quite a bit of background how many people here have you know done coding in elixir All right, that's the majority good So I'm not gonna sit here and give like an introduction basic lessons in elixir I think a few things just to sort of you know cement the ideas first idea is that We have pattern matching And pattern matching is pervasive in elixir So All right, let's really say a equals sine one you're not assigning a to one You're challenging elixir to try to find a way to make that true and it can make it true by associating the value one with a If I have a tuple CD and I try to match that against two three Obviously you can do that by associating two with C and 3d and so it goes There's a few less common forms of pattern matching So for example, we can have the binary join there elixir join to rest matches in some rocks Well, the only way of making that true is if you set rest to be the world rocks So it's quite subtle the kind of pattern matching you can do and of course the pattern matching of the lists Allows you to match either a literary or a list of the fixed number of elements like I do in the third example there Or you can match a variable length list by matching the head and then the tails the head is a single element And the tail is then the rest of the list So pattern matching applies there It also applies here So for example, I can say go to open a file and that's going to return a tuple That says either okay, and here's the file or error, and here's what we're wrong So I can do pattern matching on that using a case statement Not very exciting there, but that case that does all the same pattern matching like you do previously And we have pattern matching in functions, too We're all familiar with pattern matching in named function sorry in name functions But you also do it in anonymous functions anonymous function and have multiple heads Inside the function body and each head has a pattern match so here if the first parameter is the F and plus then that first one's going to match otherwise it is times the second one's going to match And then if here's a more common form with name functions All right, so let's just review So pattern matching Let's just match based on shape and content It allows us to destructure data that is look inside Competitive data or structured data and extracting matches individual elements and Loosely you can say it's recursive in that you can actually match things inside a match That's going on So this is a very very powerful facility And I'm about to draw a parallel between it and something else that we're all familiar with I want to just like beat the horse to death first I Think actually almost every time I stood up in this room. I had Fibonacci on the slide somewhere So Fibonacci is the Horio Chestnut of pattern matching on other things the cool thing about Fibonacci Here's a specification of the mathematical specification of Fibonacci right Fib zero zero one is one Otherwise it's n minus one and plus I said minus two Okay, so that's not a big deal and That very conveniently maps into elixic hope So here we have our module fit that has a function called fit There are three hands or three heads to that function if you pass to zero and return zero That's the long one otherwise it returns Whatever and so if you call I look for this fit 10, I guess that's 55 Okay, so nothing dramatic there So there are many ways of expressing that in elixir You could express that like this You can have one function a head Rather multiple ones and then inside that you can use a case table again more pattern match But we just have now control structure inside our function in reality In terms of executing code My understanding is that those two are identical and inside the Virtual machine those two are actually the same code. I it's mapped from one to the other It's very different at the soul slow You can also choose to write it like that Which might be how a ruby ball or whatever you think so if you look at those three Which of them best captures? the idea of Fibonacci the first thank you I think the first one the rest of them are perfectly valid the rest of them work perfectly well, but to me When I write that first one it mirrors the specification It mirrors what I'm told to do and I think that's important from two sides It's important from the developer side in that I have a clear and transparent path from what I want to do to Express it what I want to do But I think it's also clear and probably more importantly clear from some future readers point of view Because if they read that it's kind of like look like Something they can understand something that they can tie into in this case the Fibonacci specification so I think that this way of expressing things is Well expressive it's clear it's concise and it says what we want to do so I have been trying to work really hard over the last Six months to write programs as if they were Specifications and that has made the dramatic difference some of what I've heard now then just give you a few more examples and You know, they're not gonna be Specification with the list okay number entries in the list well an empty list has zero entries on the other list has One for the front of the list and then the length of the rest of the list And of course the Implementation of that the recursive implementation just follows that's fair Literally line-of-line So the length of an entry list is zero, but if any other list is one plus the length of the tail Absolutely nothing surprising Man our favorite Mac function one of the lines of function to every other list Okay, so the map of an empty list is the empty list Mac on the list of the head and the tail is you apply the function to the head and then you append the map of the tail Again, nothing that's really scary there any implementation You know trivial Okay, so these are going to like trotted out and you'll see people I'm probably guilty myself doing blog posts and tutorials that have these kind of examples It's not okay, so what? So let's try doing something just a little bit more complicated. Let's say we have a List of values in this case that numbers click at the end And we want to run the length in code them So that we're gonna look for sequences of the same value and replace those sequences With some kind of remission. So here if I have three twos in a row I'm going to replace that with a tuple with two that's the value and then three which is the repeat count This is not rocket science, but it's a bit tricky think about sitting down and coding that in your regular like a movie or a job or a seashell or whatever you might be doing Let's think of the things that you would have to think about You'd have to think about all these special cases in particular. There's the end of the list problem Right, you're going to be able to deal with that special case Did you hear me hit the end of the list and as an experiment? I sat down to try coding this off in Ruby and sure enough I actually had a bug in the first limitation. I had to go back and fix it. All right So this is where I want to get into the star of that kind of revelation I had so My input is a list and there are two special cases In that list the first special case is if the two first the head and the second element of that list are the same And just a pattern match. I represent that by just saying a name saying quote variable there Means it's going to be the same value So that will only match a list that has two identical ones at the start And what I want to do is to replace those two with a tuple that has the value of a whatever that might be and a two The other special case I've got is if I've already got the tuple at the start of my list And the next element is the same value as the value I've got in that tuple Then I'm going to replace those two elements with the same value, but n plus one Yeah, so you can see that operating here is our list One nothing special so it gets coffee, but now look we've got two twos at the start of the list So we're going to replace them with a tuple But now we have a tuple whose value is two and the next number is also two. So now I'm going to replace that with two three Now nothing special. There's no matches. So that just gets copied down Three gets copied down. Oh, we've got two of those guys now So we can form a pair of those two Etc etc. Okay, so that's how it's going to work. So how do we code that? Ever we need to generate a new output from an input We're going to need some kind of value to put that into or we don't have state You just like sticking to Vincent's variable. So the common pattern is we're going to have a helper function So to end code on list, we're going to call underscore encode That's our helpful function and we're passing it the output list So the idea is they're going to transform the input list list into that output list That's what happens when we finish when the input list is empty We need to just basically return the output list and as is often the case Whenever you're recursing on the head, you're going to have to reverse the output list This is where it gets interesting Here's our pattern match to say if the input list has two identical elements at its head And then any kind of arbitrary tail Then we're going to call ourselves again replacing those two elements with the tuple a comma two All right So we're not generating anything in the output yet. We're just moving stuff in the input list We have an input list that contains a tuple which is a repetition of the value a And the element following that is also that a Then we replace those two in the input list with a and plus one last case is Okay, anything else we just copy to the output list. That's all we have to do that just work That's just an implementation effectively from the specification They just work for us time the interesting little side effect here How do you know that this particular program will always terminate? It's actually pretty easy because if you look here are our three significant patterns To a different elements to pull an element or just some random element in all three cases of recursion We remove That pattern from the list and replace it with something shorter So in all three cases our input list is going to shrink in size so we guarantee you There's all sorts of cool side effects when you start looking at doing it this way Let me show you another example. This is actually Where I've got all of this like inspiration from if you like Because when I start learning a new language, I have little exercises I do Little things that program you know, obviously the first one is always a whole other world And then I'll get into like different stuff So I'll like co-dot binary chops and this kind of stuff if I really really really want to get into a language my courage I Won't be able to my current favorite way of doing it, but it's anything but favorite To implement a lockdown puzzle And the reason I do that is that lockdown is the ugliest worst specified For the special case thing you can think of to try to pass Right. I mean to give you a clue the canonical markdown implementation is basically the regular expression from hell You know, so it's really tough to find ways Tidally to Breakdown markdown and so as a result It's a great way of challenging yourself when you're learning a language to try and find nice ways of expressing things And this is what glue your way when I was coding the links now This is probably my fourth Elixir markdown implementation. It's the first one. I actually finished because the first one actually felt Yeah, that is okay And this is actually the least on heads as earmark, but anyway Let's imagine you're pausing market. So one of the many many long down rules use that word like it is that Before heading will be a blank line some text a Line of underscores and another blank line. Okay, so that's a particular style of lock down Hey Let's assume that the first thing that you've done is taking your input and divided it into lines and done some Normalization like I'm stripping blacks, maybe or maybe not depending So we have an input list which is a list of lines well Here's a rule That recognizes a markdown header And this is actually not quite like this because I have some stuff in there, but I mean fundamentally That's what I've got my markdown, but so to pass a list whose head Consists of a black line a title a line that starts with underscores and another black line Where the title has a length? So then you replace that in the input with or sorry you actually generate that into the output by having That has a title. Yeah, so what about just done here? I've used pattern matching to pause some syntax Extract out the information I want and then generate an output set pretty cool pretty cool another example Uglier, but I mean just to show you stripping HTML comments This is a little two-state state machine written purely with pattern matching So it's switching back and forth between being outside of comment and inside of comment And we're recognizing our comments start and stop just using a pattern Again really really cool enough of those point of this first part is that you can think of pattern matching in every single context you use it as a form of parsing Now sometimes it's trivial like you know a Matches with one. Well, okay. That's a trivial pile. This is just saying I have a single element But sometimes it's way more complicated Sometimes it could be a mockdown syntax or it could be error codes returned by father over it could be anything but pattern matching can't be considered to be a Kind of pause our code that uses it is consuming stuff During that pass during that pattern match is consuming it and it can choose to generate outputs from it or It can choose to modify its future behavior by updating its inputs instead That's what we do when we're doing our own length in coding. We were pushing back onto our input list a To pull if we found two elements the same at the beginning so we can consume input we can modify input and we can generate output and Because we can look into lists or other parameters, whatever We look at it I'm not a positive expert, but I'm thinking this is probably something like LL and Awesome, but why is that a big deal? It'll tell you later So we're gonna come back to that second thing I want to talk about is functions Now we all know That a function is something that transforms data So the plus function takes two things and has it together and the sign function takes something and does a sign on it, etc So wow, okay, that's not direct But obviously there are bigger functions more complex functions as well so for example if we were writing some kind of web servery kind of thing and We get session data come in. We're gonna go through some lookup function to find out who our user is or whatever else might be the case Or if we have like a shopping cart and some payment information Then we might want to take both of those things through a function called checkout to generate an order That's not normally how we think about Functions, but this is wasn't only how I thought about functions I tended not to think about checkout as being a transformation from one stuff one thing to another thing I just thought about it as being something I did So my second revolution is this idea that I want to think about everything as a transformation Everything as being taking my inputs moving into my outputs and along the way getting closer to where I want it to be and that's Really useful because you can do really cool things with function Now as you know functions to pose so if I was doing say Anagrams then I'd want to be able to find the signatures of each of my words in the classic way of doing that Is you take the letters in the word and you sort them so if you have cat C. A. T. Then the signature would be a C. T. All right And then any two words that have the same signature are anagrams So a typical signature function looks something like that you get the word just a string you break it up into characters and then you sort those characters and Attention put them back together. So here we have we generate these code points because it's new TFA That's obviously where we're going to be And then we sort when we join them and you know being sort of like, you know Programmers would say the way they've always been variables We don't want to use and we might be tempted to rewrite that like this Is that we've lost We've lost the ability to see what's going on in terms of functions because we have to go read this From the inside out think about someone and you're trying to explain to say your brain mode and you're trying to explain what this does Okay You say okay, so what you actually have to do here is you have to go along and Find the last function call in this and you recognize the last function Because it's going to be the thing just in front of the last opening round bracket Now what follows that is going to be the parameters for that function Okay, that's easy So you're going to go and you're going to get that word and you're going to pass it to the code points function And it's going to change the value now What are we going to do remember that last open parentheses now? We're going to skip backwards keep going to another one right and we're going to take whatever the value is code points And we'll pass it to so again explaining like this and extend like this and either we give up or she walks out Right because it's crap. It's really complicated. It's unnecessarily complicated. It skewers what we're trying to do and so elixir Among that a whole bunch of functional languages allows us to write that instead Okay, so we can pipe a value through a function and Then we can pipe the result of that through another function etc etc as much as we want So here our word is being transformed by code points That is being transformed by soul that is being transformed by John Obviously the pipeline is nothing more than some syntactic shoe Right all it is is a transformation from that form into the previous one And yet it is a profound difference to the way we write code come back to the idea of a shopping cart and Check out being a transformation of a car payment into an order So you can imagine that we're expressing that here in a pipeline And we can think about our code Purely in terms of transforming data purely in terms of functions if you start doing that It also changes the way you think about program so It allows us to express all of our work in terms of transformations We're no longer telling the machine what to do We're describing what we want done And that's actually subtle, but it's a big difference We're separating our data and our functions and we're looking at our code in terms of the flow of data and the Transmutation of data by lots of different functions And that allows us to code way way closer to the actual problem in there. So two things We have the idea that that is actually is a form of pausing And we have the idea that functional programming is a series of transformations So what does that get us to? Well, it gets us. I don't know is the answer But I want to try and show you where it's got me and this is where I'm gonna get into the kind of like, you know They was crazy. So Forgive me. Let's start with a simple function that looks like this Okay, so we're getting some kind of response probably like the GDP response just given the numbers And it's got a code and a message if the code is 200 we do nothing if it's 404 we say not found if it's 500 we do something else Okay Perfectly valid function No one could criticize that Does one thing relatively straightforwardly? No problem at all But let's think of it instead in terms of pausing and transformation we could rewrite it Like this now what we have is one function Actually equivalent of top function here one function Where to respond appropriately given whatever that code is but you're going to say oh Well, that is clearly a better way of writing it in the first form No, you're not because it probably isn't at this point, but this is all part of the build-up. Okay, so trust me So what we've done is we removed logic for the body of our function and instead turn it into a very very trivial part All right. We're pausing an HTTP response By matching different things in our function heads All right, we've replaced imperative code with pausing That's the whole point of this slide or writing all these deaf things So just as I go to save myself time. I actually wrote a little macro called a deaf My god, I love the fact that I got a language where I can do that And so that's actually off in the next if you want to use it. It's called multi-dev But it basically does the same thing if you say M deaf forms once it just generates those three function heads Okay. Now it's getting a bit clearer. I kind of like that. So here's a slightly more complicated case Again perfect in reasonable code. We want to read a line from a file. So we're going to open the file I'll find that open returns a tuple that says okay, and it's some kind of device I own for me And which basically we can read from it. Otherwise, we're gonna have some kind of error. Yeah So that's again a perfectly valid nice little subcontain function Now you put on you it does two things. So maybe it should be But I don't know but I want to think about my world in terms of pausing and transformation So here my first step is to say well the return from file.open is something that I can pause And so I'm going to split that out I'm going to say that to read a line I am going to call my little helper method on this little line and pass it the result of opening a file And then in my helper method I have a pass to say it's okay. I'll do one thing if it's not okay I'll do another thing Okay So here again, I've replaced imperative logic with declarative pass But I can take that step further and make it obvious what I'm doing By using a pipeline to show the transformations that are taking place The transformation is I'm taking a name and then transforming it into the first line of a file with that name And by writing it like this I'll make that explicit So I have my transformation going that way. I have my pass Going down This is getting interesting at least to me Excuse me for doing this This is actual code from IEX. It's the code that loads the .iex file Which is the one that does all the initialization if you want to customize your colors and everything else So what it does is you can pass it explicitly the path to your IEX file in which case that's the one that it loads Otherwise it's going to go and look for either a .iex in your current directory or in your home directory yeah so The first of all says if you give me a path then the only candidate is that path Otherwise I'm going to take all of the you know known names and expand them into a full path name And then I'm going to find the first one of those candidates that actually exists as a file If I can't find one then I'm going to return the original config Otherwise I'm going to merge in that new IEX file into the config that gets passed in again An okay function a fair amount going on in there, right? I've had to write or somebody has had to write You know some if statements and some conditionals and blah blah blah right? Can we do that differently? We could do it using transformations and pauses So it's a little bit like taxi x.iex file We the fundamental thing we want to do is to take a path We want to go and use that path to find the possible IEX files find the first one that exists and then update our config from there That's pretty straightforward Yeah expresses a transformation like that. It's really obvious what we're doing I think it's easier to read putting on with if statements Now to get our IEX files we're parsing our input And it's a trivial parse our input could either be a name or it could be nil So if our input is nil we're going to return the list of possibles Otherwise we're going to I should have got to expand it all Otherwise we're going to find the path And then to find the first we just use the existing code and then finally We're going to pause the response of finding that first one if we find it We're going to merge it into the config if we don't find it We're not Again, we're replacing imperative logic With pattern matching and transformations In beginning to see a pattern here. I think that this is worth exploring My current lockdown parser is I think it's about 1200 lines It has a total of I think it's 11 Imperative statements in it And some of those also do with how I mean I could probably hear a little bit if I really really wanted to I think it heard a little bit It turned out to be actually I think Nice total means there was imperative statements So Once I've worked this style out once I've worked out that this is how I wanted to do this It would believe how much simpler it got How much easier it was to do I needed to add I I released the first version and then I wanted to add table support And it was just The modularization that comes from the cars was so beautiful I just said okay to recognize a table I have to parse a line to recognize one a table has to have Two successive lines to have the same number of vertical bars So I can do that as a parse the whole thing just fell out It was like half an hour's work I was expecting that all the day is what I thought about It's a phenomenally fun way of coding on all sorts of scales For example Maybe we're writing some kind of back-end service rest service And we're doing some kind of site that does You know deals or coupons or whatever else okay, so I'm a particular user Or I'm doing on behalf of a particular user And they come in through some kind of rest of the whole tokens So if we go find the user and then for that user I have to find their local offers You know the ones that are around them and then the kind of national offers like chain stores that are giving me discounts or whatever else And then I have to get those responses Merge them and send them back down as a response to my rest interface All right, so this is kind of relatively straightforward stuff when you want to serve So I want to think about this now Not imperatively, but I want to think about it in terms of transformations and parts. Oh, I'm just making it interesting I'd like to make those two asynchronous All right, so I'm going to send out the two response the two requests to find the local offers And then we can vote to come back before I send a response down So it's going to look something Like that all right this next slide is I'm going to say all these slides this one is ugly, but I still like to think about it a bit Because I would express all of that Using pattern matches and you're using a few simple transformations. I'm just showing the pattern batch part there I'm not going to show the actual functions that do it, but let's assume it looks something like this My response comes in my request comes in And the little front end thing converts that into a map Where it says get offers and here's the authorization total Okay, and this is going to probably go get handled by Some kind of gem sort of component somewhere this signal how to make these things so the first thing that's going to do is match on that particular map Actually value And the first thing it has to do is find the user so it's going to respond by saying, okay So now what I'm doing is getting offers. I have a user so it's going to look up the user from the call and stick it into that map So now we have a map of the two elements in it One's the one's the request type one is the user. So now we have a different pattern match So I'm going to come in now with a second pattern match. So we're just looping around calling ourselves trying to pass this response And we've made our input more complicated. We've added things to our input just the we did with the run length encoded thing Here we've added the user to our input So now we match that now we're going to call two functions async get local and async get national And they're going to go off and do their business We're not going to do anything else. We're not recursively calling ourselves at this point They go off and do their business and at some point they send The responses back into our server and our server is going to use those to update its state update its input Now and if the national comes back and says hey, there's an error Then okay, we're going to throw the whole thing away just to respond to the error Similarly if local comes back and says there's an error They're going to throw it away Otherwise we just need to pattern match the case where we actually have national data and we have liquidator at that point We can send the response back if I could work out the time and whatever else I would love to see Some kind of server implementation Based on those kind of principles. It's a server implementation where it's declarative Where the rules are obvious What we code is what we wanted to do and not all of the little kind of details of capital coding Now This is not new It's One of my one of my real pet peeves is that it's an industry we have no memory Or we keep reinventing things that we've done before Um But this goes back to the 1960s total programmers Used to use decision tables Which will come with varying State machines again in the 60s are varied on this And gluttonous limba blackboard system and all the others like that are also varied in that you put data into the system And then you pattern matched In order to generate an output So this is not new. This is nothing, you know, totally radical, but for me It is for me. It's a different way about thinking when I'm writing code And I am finding that incredibly powerful once you think about things this way You get all these extra benefits too It's easily made in parallel Um, effectively you're writing a dsl I mean if you think about that previous slide with the maps that's could be considered to be a dsl But you could wrap that in a really nice little dsl a specific time just as far as you can get really long to do You get for normally granular reuse Because each function I mean typically when you're writing code this way every function is one line long So if you want the ultimate granular reuse, that's it If you're into testing clearly you're easier testing Right because you can put around everything that I say is one line long. You can test just that one thing Really nice and easy to do And you also get control of error handling. I think Bruce you're going to talk about your pipe Like this right? Oh, okay Um, but I mean you can actually start codifying error handling when you heard of things as a part of us Then there are easier ways to handle errors You can also start thinking about error recovery I mean the parser literature is full of ways of handling error recovery in a graceful way We can start using that in our code Yeah, it's kind of interesting. I'm not saying throw away your statements I'm saying I have And I'm saying it's really interesting For me personally to have done that And I'm having a blast exploring or re-exploring what it means to partner I don't think I'm advocating this as a universal solution for everybody that wants to code But I'm saying the kind of changes that have Is ruled to me have been so beneficial and so refreshing. I would like everybody else to experience change too Do it for yourself find ways for yourself To think about things differently I think One of the biggest benefits of elixir is that it is a breath of fresh air for developers It's the ability to have a fresh start We can think about things in a different way and I think If we do that the most important, I mean if you like we are Around which this is going to stop forming. Okay, the 105 people in this room Are you know the start of something and we get to set a lot of the direction Right, what if something is so young and so small That every little input is going to be significant. We get a chance to do that And that's fundamentally exciting So Here is my plea Some of you may come From the Ruby community Please, please do not give us another rails It's easy right rails works rails is cool. Okay, so but Linux doesn't have a rails therefore we need to do Well, L rails or something. No you don't right That's boring. That's being done and it doesn't solve a problem Maybe you come from the early on community and you see this as a way of A bit easier syntax for creating the same applications you'd be creating with us Again, I would say please don't do that This is the opportunity we all have to throw away a whole bunch of stuff. We've got a free Restock, you know and that is so cool. So instead of reinventing the past Let's use what we have here. Let's use the power of what we have here to invent a new future All right, let's think of cool things we can do with this opportunity And let's make a difference And then while we're doing that, let's just remember to have fun So, thank you very much