 Mae'r dros i gyd wedi bod wedi bod yn perthynig i'ch meddwl ar y cynnig. Rydyn ni'n gweithio arall erbyn. Rydyn ni'n ddweud hawt yw adopting brofyn, Ac yn cynnig o'r llam. Rydyn ni'n ddweud am ymddech chi'n gorfin i'r EU. Doedd yw'r cyflwyffydd, mae'n gyflwyffydd ar y ddweud. Mae'r cyflwyffydd yn cyflwyffydd. Roeddwn i'r llwyddo'r ysgrifennu. Mae'r peth yn bach i'r gyda'i gwybod llawn, o'r ddweud o'r 3 o'i gyrdd. Mae'n gwybod yn bach i'r gwybod. Ond yna phoedd phoedd phoedd? Ond wedyn, mae'n mynd i'r rhan o'r grwp yng nghymru yn ymddangosio'r phoedd ond mae phoedd phoedd phoedd yn y Web Framework bydd yn Alexiwr. Mae phoedd phoedd phoedd phoedd phoedd phoedd yng nghymru a beth yn bach i'w ffrif. Ond yn ddweud, mae'n ffrif sy'n rydw i'r chyfodol Waiting at the conference, but some of the reasons we are interested is because it has all the power of beam and OTPs and all the history and words that those have had, but it also has a beautiful syntax with Alex here. One of the things that we really liked about rails and Ruby was that it made me very productive because it was really an expressive language to work with. And do we feel the same way about Elixir as well? So, of course, the tagline on the website for Phoenix is it gives you both the performance and scalability of Beam plus the maintainability that comes with working in a programming language that's a pleasure to work in. Also happens to do HTML5 and APIs very well as well, which is great when you come to use Elm. What is Elm? Elm is a functional programming language that has an ML language style syntax and it compiles down to JavaScript. So, yes, it is another one of these languages compiles down to JavaScript. It's slightly different from the likes of, for example, say, CoffeeScript, where the idea is just to write JavaScript in a less painful way. Whereas Elm, you don't really write JavaScript in Elm per se, you write Elm programs in Elm, they just happen to compile down to JavaScript. It uses JavaScript as its runtime. So, why would you consider Elm? Well, Elm, obviously, because it compiles into JavaScript, runs anywhere JavaScript does, which is everywhere. So, you can run Elm on your fridge probably, I don't know, I've never tried it. It has good JavaScript interrupt, which is good. If you're going to run an environment for a language, you really want to be a good citizen there and you want to play nicely with existing tools. Elm also has a beautiful syntax. It's kind of like Haskell, but it's a lot more succinct in my limited experience. Elm is statically typed. Now, I came from Java and when I saw that it was a typed language, I don't know. But, as it turns out, Elm, the static typing in Elm is fantastic. It really helps you. It doesn't hinder you. It doesn't involve a lot of typing. In fact, it has typed inference. Most of the time, you don't even have to tell Elm what type of thing is. As long as it is of that type, it can infer. This is something that comes in really useful when we port in stuff over JavaScript, as we'll see. It's also blazingly fast. To do MVC being the kind of benchmark of front-end frameworks, we have the usual caution about benchmarks to add. Elm performs better than React. It's because it uses a virtual DOM in the same way as React does, but it's also completely mutable and pure, so therefore it can get massive speed gains there as well. Interesting to know, on Mercury, they're both also using mutable state and a virtual DOM, which is why they have speed increases they do. What does it look like? Let's see if we can do this. Can everybody see this? Let me see if I can get to see it as well. Excellent. This is Elm. This is just on the elmlang.org tri website. I've got a sample app here that they provide, which is a counter. You'll see on the right-hand side here, if you click the plus button, it counts up, and if you click the minus button, it counts down. Very simple. At the top here we have imports for importing libraries. This is the HTML stuff that allows us to put HTML out on the screen. An important one is startapp.simple. Startapp is a way that Elm has to do wiring for you under the cover, so you'd actually have to know how everything wires up underneath Elm. You just provide it three things, which in this case is a model, an update, and a view, and it knows where to go from there on. It's important to note Elm has a model update view architecture. It has a model, which is a mutable, an update, which it uses to step the model from state to state, and a view, which allows you to compile that to something that the user can see, in this case HTML. Every Elm application needs to have a main function, which is a start point, same as C. Here we have our main method. We call start, which is from startapp.simple, and we pass it in the model update and view. Incidentally, this thing here is called a type annotation. It is entirely optional, but what it does is it states after the colon what type, in this case, what type, sorry, the return type is for this function. It will be a signal of HTML. We'll come back to this later on. If you want to have a look at one that's slightly more involved, the update here, it will only have a return one type, so the last type here is the return type, and the two types, or any number of types before that, interspersed with the stabby arrows, are the parameters, or the types of the parameters that are coming in. Okay, so our model here is stated to be an integer. Type alias model to integer basically says, whenever I say model, I mean integer, and then we initialise that to be zero. Our update states the types of action that it will allow. In this case, it allows an action of type increment or an action of type decrement, and it then uses pattern matching when an action comes in to the update function. If it's an increment action, it will take the model, sorry, this takes an action, the current model, and then the new model that's produced afterwards. So the action that's passed in, let's say it was an increment, what that will do is it will take the current model, it will add one to it, and it will make it the new model. Now it's important to note, this is not modifying the state here, this is not saying take the current model, add one to it, and then return the current model plus one, you're making an entirely new model. The decrement obviously does the same, but it does a minus instead. And the view function here, it takes, let's ignore the address just now, it takes the model or the current state of the application, and it will then display it out to the user. So in this case, we have an element, which is a div element. The first list is the attributes, and the second list are the elements. So in this case, our div has no attributes. As it's elements, it has a button, which is our minus button here, and it puts out minus its text. It also has another button here, which is the plus button. And as a div in the middle, which takes the current model, which is an integer, two strings it, and then presents it as HTML text. So there we can see we've got a zero. What this address does here is this lets the view know if it has any events to fire back through the application where those need to go. So this address in this case is to start up, and start up will know that when it gets an action in on that address, it needs to reach it to the update function. So when you click this button here, it will decrement, or send a decrement action, sorry, through the application, and if you click this one, it will send an increment action. Okay, so far so good. Looks quite complicated for something very simple, but let's have a look and see what we're actually doing in the background here. Okay, so what we actually have here, you see my mouse pointer? No, we can't. Hey, right. Let's see if this works. Yes. Okay, so what we have here, in fact, not too easy to see, but we have a signal of type model. A signal in Elm is an attribute, sorry, a value that can change over time. Signals, when you first look at them, look like streams. They are not streams. They are a single value, but they change over time. Now, remember, Elm is immutable, sorry, the values in Elm are immutable. So the way that it deals with mutable state is it has signals. And each time you put a new immutable state onto that signal, sorry, a new immutable value onto that signal, it's kind of like a changing state. And then that flows straight out of the rest of the application. So here, we have a signal. Each of these signals will have a type. In this case, it's type model. The model, remember, is an integer. So in this case, the first value or the initial value on this signal is zero. And then we have a signal of HTML, which shows the current model as HTML. In this case, it will be a view with zero. When we click the mouse, we have a signal that goes through as well. This is a unit. It basically means something has happened. We don't care what the value is. So a mouse click is a card. We then have another signal, this time a signal of action, which is generated by our on click. Well, this on click basically does, it says, okay, I've got a click. What button is clicked? It was an increment. Okay, I will send that increment action to the address. The reason we need a signal of action is that our update function only understands actions. So that then gets sent, sorry, doesn't get sent. The start act will know that a new value has appeared on this. It will run the update function, which will run the increment, and it will create a new model and we'll get one on our signal model. That then, of course, then gets viewed as well. And that happens every time we click the button. So we click the increment again, exactly the same thing will happen, but this time we'll have a two. If we do the decrement, it will take one away instead, so it becomes one and so on and so forth. So the application is always reacting to whatever happens on those signals to change those signals. This is known as the Elm architecture. So it's a little bit tricky at first, and I'm going to show you this diagram, and I'm going to show you a much better one. So this is one from the Elm site. And what this shows you is that signals are basically these lines flowing down here. Now you want to map signals into the correct form. So when you first come in, say we've got a signal of integers or a signal of model as we had, or even if you've got a signal of something else, you need it to be an action, so you map it into an action. And the map works the same way as map does on collections, for example. It just says take the latest value off of that signal and change it into some other form. Because of the fact we only have one update function, we need to take those signals of actions and combine them all together, and that's what a merge does. A merge basically says take signals of the same type and merge them into one signal, one overall signal of that same type. Fold P. Yeah, I'm going to have to explain this. Fold P means fold past, and what that basically means is when a signal comes through, every value that's on it, because it's a value that changes over time, take the past values and pass it through this function. It's where you're allowed to have side effects. This is where you're allowed to do things that are not necessarily immutable or not necessarily pure, sorry. Fold P is happening in the background with our startup, and it's going to pass things into our update. The result of that will then come through to the other side. There we go. Okay, yeah, sorry. You can then further filter if you want to, or you can just come straight through. Okay, so that's the science bit. Luckily, Jess, who's doing the keynote later on, had a much, much better diagram, which she let me borrow. Thank you very much. This is basically what's happening here. Much easier to understand. There's a human being somewhere that's looking at the HTML from her app, and they click a button, an event will get passed in to the update function. The update function then steps the immutable model from one immutable state to the next immutable state. The view function picks up those changes and does wherever it needs to be to generate the HTML, which the user can then see, and so on and so forth. This is in its simplest form. There are other things that can affect things as well. Okay, so time for an example. So what I'm going to do, and this is going to be really basic because we just don't have time to do too much here, but I'm going to create a seat saver app. So whenever you book a flight on a plane, one of you check in, it allows you to choose your seat. Now I've made this really, really simple, just enough so that we can see what it actually is. It has been pointed out to me that it looks more like a boat than a plane. And also we don't have seat numbing like that on planes anyway, but this is fine. It's just simple for an example. Plus I don't want to use too much CSS because as we all know, CSS can kill you. So the foundation of our app. What we're going to have to do now in order to interact with something outside of Elm. So we're going to have to interact with Phoenix here. In order to do that, we have to allow interoperability between Elm and the outside world. And the way that we do that is through something called ports. I'll come to that later, but it means that we have to use a more, sorry, a fuller version of StartApp. We're not using StartApp simple now. We're using StartApp. StartApp. StartApp. So what this takes rather than model update view is it takes init, which is your initial state, kind of like your model, we'll see why in a minute. It takes the update in the view as it did before, but it also takes a list of inputs and these are external inputs. So these are inputs that come into your app from elsewhere. And we generate this or create this in an app function. And that in turn, in our main function, which we have to have as a signal of HTML, takes the HTML that's done inside StartApp and pulls it out. Now there's another function that's required here as well, but I've missed it off just for clarity. So in our initializer, what we need to do is we need to represent a seat. A seat is going to be a record that has a seat number, which is an integer, and an occupied flag, which is a boolean. And then our model for a particular app here is going to be a list of those seats. So that is just a standard Elm list and it has the type seat. Now in order to create an initialize, I'm sorry to initialize this, rather than just passing the model initialize, we also have to deal with something called effects now. Effects are complicated and I'm not going to give you the full definition of effects and that's not just because I can't. But to keep things simple, effects are things that can happen in your app that do not directly change the state of the model. They may result in the change of state to your model, but they are not immediately going to do that. Effects are things like animations or HTTP requests or things such as those. So in order to initialize our app now, we need not only the model, but we also need to have an effects action. Or in the case of initializing, we're actually just going to have an empty list and an effects.none, which is a way of telling Elm that you don't intend to have any other effect. So that's our initializer. Our update now needs to change slightly as well. You'll notice from here that when we did the update previously, we had an action and a mod, something of type action and the current model, and we'd return a new model. Well, now because we need effects as well, what we're going to have to do is we're going to have to take an action, take the current model and return a new model and any effects. Sorry, the current model or any new effects. At the moment, we do actually have any action, so I'm going to create a know up. All our know up does is it returns the current model and no effect. So it's not making any change to the model and it's not having any other effect on the application. Our view for this app is going to be reasonably straightforward as well, slightly more complicated than before. What we have is an unordered list and that unordered list is going to map around our model, which remember is going to be a list of seat objects. For each of those seats, it's going to call the seat item partial and the seat item partial is going to create a list item, which is going to pick the seat number in string format. These classes are purely for the CSS. So to go back to our signal diagram that we had before, what we are starting off with here is we're starting off with a signal of model, which is going to be an empty list which came from initializer and our signal of HTML, which is going to be a view of that list, which is going to be a canoe. I don't know if you can see that very well. So yeah, basically we don't have any seats in there yet because we've not initialized it. So we actually want to get the seat data from the database and we're going to put Phoenix in between because it's great. So I thought, okay, excellent. I really want to find out how I can go and do this. I want to set up a channel. So surely somebody's done this before, so I typed in Phoenix and Elm and I got this. If you don't recognize it, this is Harry Potter. Apparently one of the ways you can make a wand is to take Elmwood and to insert Phoenix Feather and they're really great ones. I draw an analogy about magic and how Phoenix and Elm are a magic combination, but I'm not going to, well I just did. So well, how can we actually do this? What ways do we have of joining them? Well the first way and probably the simplest way is to keep them completely separate. You have an Elmap. Your Elmap runs a static app inside the browser and it uses an HTTP request to talk to Phoenix, which does some really, really nice data APIs, very simply. And this is the way that I actually started out with doing it. So I was going to talk about this in here and I know it says on the notes for the slide I was going to talk about it, but I'm going to run out of time if I do this as well. So there will be a separate blog post that will come out about how you do this. It's very straightforward, but it's not really taking full advantage of Phoenix, I don't think at least. The other way is, well when you compile Elm, it just creates standard JavaScript, ES5 JavaScript to be precise, so you can just vendor it, stick it in your static vendor and use it as if you were using any other piece of vendor code. The reason I've stuck it into static vendor incidentally is because of the fact it produces ES5 and brunch itself in Phoenix by default not to do a transpile for stuff that's in vendor. You can put it anywhere you like and you can set up your bunch to do that. Excuse me. Okay, so that's the second way, the third way, and why wouldn't you want to do this? Stick the Elm actually inside your Phoenix. And the reason that this is good, apart from being completely insane, of course, is that it means that you can use the brunch pipeline to compile. So every time you make a change to your Elm file, it will automatically compile it and change it into the JavaScript, which then gets passed through the brunch pipeline for JavaScript and results in your RGS, or however you have your brunch set up. So what I've been doing is I've just been creating an Elm folder inside web. The reason I'm not sticking it inside static is because Elm in the Elm stuff folder, which is kind of analogous to node modules folder, it will have native JavaScript in there because quite a lot of Elm stuff has native JavaScript bindings. And if you put it inside static, then it will get picked up by the brunch compile and you'll get a whole pile of cruft appearing in your app.js and it will crash, and you'll spend two days crying and trying to figure out why it's happening. Or not. So I just stuck it in a separate folder and it seems to be working for me just now. There's this Elm brunch plug-in, which is fantastic. It was created by a guy called Mads Flenstead entirely indebted to him for this. And what it allows you to do is just stick into your package JSON as high as you possibly can because brunch will read these packages off an order. Whoops. To just call it to Elm brunch. So I've basically stuck it right underneath brunch because you really want that to happen before all of your JavaScript pipeline stuff happens so that Elms converted it into JavaScript. Then inside your brunch config you just set that up as well. So you've got set up the watch file. I've set this up just to watch the Elm file. Again, don't ask it to watch your entire directory because then any time any JavaScript in there changes, it will also compile the world and stick it in. And then you just configure the plug-in so that Elm brunch knows where your Elm is inside your Elm folder. Any of your Elm files that have a main function, it knows where those are as well and where you want it to output to. To get it into the front end of your app. Well, it's entirely up to you how you want to do this. For just now, for playing around, I just went to the pages index HTML which we got given and stuck a div in there with an ID. You can then pull that out and then create your Elm app which is using Elm embed, takes the name of your module, in this case Elm Seatsaver and the div that you want to embed it into. Now you don't have to embed into a div. You can actually do it full screen in that case you do Elm full screen with Elm.seatsaver and you miss out the div that you want to put it into. The result, again, is the same thing because we're not passing anything in yet. So what do we actually want to do? Well, this is a very, yeah, it's a diagram and whoops. What we're basically doing is we're taking we're taking data out of the database using Ecto and we're passing it through channels out to each of our Elm clients. So that's what we intend to do. So setting up a channel, in case you need to know, what we're doing here is we're creating a seat channel and in that seat channel we have a basic query which just basically gets all of the seats and orders them by their seat number and it passes out in the payload on a successful response. We let the user socket know that we intend to do that and one other thing we had to do here is because we use snake case in elixir, we have to convert that into camel case and we'll see why that's important in a minute, but this was just a quick poison encoder that I set up to do that. In our app.js or in another more suitable place you unlock, sorry, or uncomment the import socket and then you open the channel and do the channel join. On an okay, all we're doing is console logging out that seat data just now and on an error we're going to console log that out as well. So how do we get this data into elm? We use ports. Ports is a way of talking to elm from the outside world and talking to the outside world from elm and I should point out, as somebody asked me to, that elm ports are not airline ports. They kind of serve the same purpose sort of, but they're not the same. So don't confuse the two of those. What a port does, at least an incoming port anyway, is it will take a data structure in JavaScript. So for example here we have our list of seats and those seats are just seat objects in JSON. On the elm side, this is quite hard to read, there is use the port keyword with the name of the port that you want to create and then what you expect to come in over that. It's going to be a signal the same as everything else and in this case we're saying it's going to be a signal of model, our model as you might remember is a list of seats so it's going to expect whatever comes in over that port to be able to be parsed down to a list of seats and this is why we made our seat number, seat number with camel case because elm uses camel case inside here. So if we do this we can just use a nice little bit of code here which takes elm app which is available we set up to hold our elm app in JavaScript. We call the ports function and the name of the port seat lists here and we just send data to it and elm will happily take that and it will turn it into elm code underneath. So it will turn that into a list of seat records. Excellent. So we create that port inside our application and then we go to our app.js file again and we now instead of console logging out the seats we use the elm app.ports.seatlist.nseats and we get port error. Now the reason I left this up was for two reasons. First of all is to show you that that port error happens and secondly is because look at how lovely elm error messages are. They tell you exactly what you want to know. So it's saying you haven't given me an initial function that's our initial data with the type seat model. You need to provide an initial value. So let's go and do that. So where we went and actually created our elm app in the first place we can then go and create another variable just to keep things readable which passes in an object which is a seat list with its initial value which will just make an empty list and then we pass that in as the third argument to when we do the elm embed or the second argument if we did elm full screen and we still have no seats. Why have we got no seats? Well it's because we have a port here which has the incoming data which is a list of seats but we've got no way of passing into the app. StartApp doesn't know about this yet. So in order for StartApp to pass it through to our update as you might remember from before we need to have a signal of action. So in order to change the seats into a signal of action we use signal.map. So what this basically says is for every value on seat lists which is a third word there. For everything that comes in on seat lists turn it into a set seats action. This is a bit of syntactic sugar which can look a little bit confusing so let's expand it out to what it actually does. So for every seat list that comes in on the seat list's port pass it into this anonymous function and then convert it into an action which is curried with that seat list. It's important to note we're not actually calling this action just now we're just creating that action and currying it as a partial function with the seat list that we want. We need to let StartApp then know that that signal exists so in the inputs down at the bottom we add the incoming actions as an external signal and then in our update action we create that set seats action. So we make the type set seats saying it's going to have a model a param of type model and then down in here inside the case of it pattern matches to this action it will take that list of seats and it will swap the current model for that list of seats. It will take list of seats and completely swap out the empty list we had before and put in that seat list and then effects.none because we don't have any more effect. So to go back to our signal diagram to see what's happening we start off with a signal of model which is a list of seats. We then convert that into an action which is a set seats action with that list of seats as its parameter that goes through the update method and it changes the model from being an empty list to being that list of seats and the view will then go an update and the result of that is a list of seats. Now I know that's not hugely exciting but in order to get through there we've had to jump through our fair few hoops. The next thing obviously we want to do here is we want to be able to click on seats and to have this happening in multiple browsers and all the rest of that you will be just about to know I'm not going to have time to do that today unfortunately. I'm going to have to go to my conclusion. So the conclusion is that elm and phoenix do seem to me to work really well together. There's been various discussions both on the elixir lang discussion group and on elm discuss as well about how these can can play nicely together. We're not entirely convinced courts is actually the best way to do this mostly because of the fact they're one way so if you send for example if you click on a seat to go and ask for it and it returns an error you have to handle the error in the javascript that happens in between. So either we need a custom channel implementation or we need to do something in elm or both. There are certainly discussions around both so I'd be really happy to talk to anyone who's interested in talking about this or wants to join the discussion online. I'm going to take what I've done so far with figuring out how these things work so far so the HTTP side of it the web sockets and more advanced I've turned these into kind of tutorials online I'm not finished them unfortunately I was ill last week so I didn't manage to get them finished and when I'm going to get those done and when they are done they will be available on the Cultivate HQ Github organisation and I will tweak them out on Cultivate HQ Twitter to let you know that those are available if anybody wants to follow along with those. In the meantime some other excellent resources and there's a guy called Richard Feldman who did a fantastic talk at strange loop about why you want to use elm and production and why it rocks over javascript so other javascript frameworks and why you might want to consider it so definitely check that one out. Elmlang.org has got fantastic information that they've got guides which will help you go through these things especially look at the Elm architecture tutorial one because it tells you a lot of things you want to know about Elm. Elm discuss and Alex here Lang both of those discussion groups have got discussions on going around this. Pragmatic Studio the fantastic series of courses that they've done on Elm that Mike Clark's done and the first Elm course is really what kind of got me into Elm in the first place. The Elm Signals one is great for for taking you on that step further and the only book that I'm aware of so far apologies if there are more and the only one I'm aware of is Seven World Languages and Seven Weeks has a chapter in there on Elm as well. Excellent perfect so sorry that was saying it's been updated to 0.1 0.15 yeah okay excellent thank you very much. So yeah let's make amazing things. Any questions?