Sessions is temporarily moving to YouTube, check out all our new videos here.

Elm: the Good, the Bad & the Alternatives

Jon Kelly speaking at Front-End London in April, 2017
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

Elm has become well-known for creating highly-resilient web apps with elegant, readable, code. By seeing some code and a demo of both a very simple Elm app, and a more complex one (that interfaces with JavaScript and D3), we'll look at benefits, functional programming concepts, pros and cons, and finally, patterns implemented in an Angular2 JS app.


Jon: All right. Thank you. I'm really pleased to be talking here tonight about Elm, because I think it has some really interesting things to offer. I would also say this talk is very much in the spirit of exchanging ideas. It's not a talk to say, "Yeah, this is the best new thing. We should be doing this new thing, and no other things, and every other thing we've done, that was all wasted time until we do the new thing." It's really to exchange ideas, so [00:00:30] everyone's feedback on this, what we all think, is it a good idea, is it interesting, that's as important, far more important than one person saying stuff. So with that in mind, please interrupt me while I'm talking. There's kind of a lot of things here that might look quite strange, or just be unusual, and that's fine also. If you just want to let it go by, and just grab it here or there, that's absolutely perfect, but, yeah. [00:01:00] Do absolutely feel free to chip in, because also there's a lot of stuff. We probably won't get through all of it, so if we focus on the bits that we most engage with, that's brilliant. Actually, let's say "What the hell is Elm," before I say why Elm. Well, personally, Elm ... If we write for the front end, generally we're mostly using JavaScript. We might [transfile 00:01:27] JavaScript into various versions, Babble, [00:01:30] Babel, whatever it is. Whole bunch of things. Whereas Elm is one of the ideas, perhaps a bit more like ClojureScript, or Scala.js, things like that, where you actually take ... You never write any JavaScript yourself, although we can see that it can work with JavaScript. Basically, you write Elm, which is another language based on some functional languages, and that gets compiled to JavaScript for you, and [00:02:00] yeah. That's it. So why Elm? Basically because JavaScript programmes just crash. I'm a fan of JavaScript. I really, really like JavaScript. I've done various other languages, compiled languages. I like JavaScript. You can just get on with it. I like the fact it's not so fussy about types. It's sort of flexible. It seems quite a bit verbose, but it's expressive. It just crashes all the [00:02:30] time. You go off and get some JSON, and that JSON is missing a field, and then your code crashes again. Elm, one of the biggest things it's designed to address, is to stop our code crashing all the time. So the good about Elm is it does make apps ... We can write something, a JavaScript programme, and it'll be so resilient. [00:03:00] Yeah, you may get the logic wrong. It doesn't stop us getting the logic wrong in our code, or anything like that. It doesn't magically know what we were thinking rather than what we were typing, but it's hugely resilient. I've thought, actually, before, when I've talked about Elm, I've thought, "Well, I'm nervous about lots of things. Can I explain the concepts properly? Yeah, I'm looking at lots of people and they might ask all the good questions." The one thing I don't worry about, although we'll try and disprove that, one thing I don't worry about is will the programme crash when [00:03:30] I demonstrate to people. You just get to rely on how resilient the programmes are. There's this thing called ... No ... Yeah, declarative. Declarative's a bit of an idea from functional programming. It's the idea that you kind of ... Perhaps you'll see that ... I'll be interested to see whether we feel that, looking at the code. It's the idea that you much more say what you want to do rather than how you're going to do it. [00:04:00] Maybe if you've used things like D3, or RxJS, you might also have seen that as an approach. It's a big underlying concept for a lot of FP stuff. Elm is very, very fast. There's no ... I think the download [size 00:04:20] is supposed to be pretty decent. I haven't studied that in too much detail. It is super fast. You're not giving up anything, [00:04:30] in terms of speed. You're gaining a lot. It's very accessible for the type of language it is, and that's something, I'm never quite sure the term, but it comes from a functional programming language called Haskell. Oh, anyone heard of Haskell? Wow. Crikey. Male Speaker: [inaudible 00:04:49] Jon: Yeah. Haskell, it's one of those things ... A lot of Haskell [00:05:00] programmers, although they're sort of a relatively small number, they're all waiting for Haskell to take over the world. And, yeah. That may happen. It's still ... Seriously ... It depends what forums you read. I've been talking to a friend of mine about it for about 15 years, but it's now starting to get closer to the browser, so who knows? [00:05:30] But Haskell is not famous for being accessible. It's famous for being amazingly inaccessible. So with Elm, basically, it's really, really accessible for what it is. A final good thing, and this will also appear on the bad things, if we get as far as the bad slides, it's not built by committee. The driving force behind it is a guy called Evan Czaplicki. [00:06:00] He did his PhD thesis on it, and continues to be the driving force behind it. He really is the one, main driver behind it. That's kind of worked very well. He's sort of got a very clear direction. He's very focused on the audience. The audience is pretty much everyone in this room, whatever level we might be at, working on front end. That's who Elm is targeted at, which is different to other options there may be. [00:06:30] Okay. Just to start, quickly, try and do a bit of jargon busting, because any time ... I know, if you read a blog about functional programming, or things like that, you might hear a lot of jargon, and it kind of gets between you and the code you write. Perhaps the first thing you might hear is immutability. [00:07:00] Anyone heard of Immutable.js? Oh, cool. Yeah. So a lot of these things, they might be actually bolt-on things to make JavaScript like them, but the big idea of immutability is where every day we just depend on variables. In functional languages, you don't really have variables. Once you declare something as a value, then it has that value forever. But actually, in Elm, with [00:07:30] the way it's structured, that doesn't really matter. Out of all the things that might frustrate me about Elm, the immutability, you don't seem to notice it. The way it's structured, you just feel it's immutable, frankly. Pure functions, that's a fancy term for you have very little side effects. If you have a function, it's got two parameters, and the function is to add those two numbers you pass in. If you pass in 2 and 2, you will always get back 4. You will never [00:08:00] have it say, "Oh, I got something from the web, and the web told me to do something different," or "I got something from the web, but oh, look, the JSON wasn't right, and I crashed, and something was not a number." It will always give you 4. So actually, these are things ... And by design, this is a big functional programming thing, by design, these are things actually designed to make both code easier to write, and the term is "reason about". You just look at your code, and think- Male Speaker: I'm sorry- Jon: Please. Male Speaker: This is the second [00:08:30] time that we've talked about stuff coming from elsewhere, and it might not be what you expected, wanted, or needed, and yet your programme doesn't crash. How can that possibly be? How can I get something from elsewhere, and put it into a function that's always going to return me 4, when the operands aren't 2 and 2? Jon: That's a good question. I suppose you would be separating the functions if you have something [00:09:00] that actually depends on the web. You don't know ... I've actually got some code where we see how ... It's a really good question. You've got some code where we look at how we get some data from the web. So if we're getting JSON, we specifically ... So obviously, the values we might get in might vary, so that is a bit different from ... But we kind of know, as well, we can see what sort of functions we've [00:09:30] got, but if we're getting JSON from the web, we specifically say, "This JSON format, yeah, it has name, and description," or something like that. Basically, hopefully those can vary, but let's say description isn't included, or it's null, then you simply won't get back that data. You'll get back that you've got an error. So, for instance, some code I had, or, well, it was part of a meet up, but we [00:10:00] got some data from the GitHub API. Our code crashed recently because someone didn't have a name defined for their GitHub profile. So when we tried to access that name, the JSON, bang! Down the code went. Basically, if you get some data in that doesn't match your format, basically Elm will say, "That's no good." You can define it to say, "I'm not interested in that field," [00:10:30] or you can define different formats if you know ... Yeah. So if you know occasionally the description or the name field aren't there, you can say, "Use this format or that format." Does that help answer the question? Male Speaker: Sort of. Is that to say that it gives you an easier way of handling exceptions? Female Speaker: Can I just [crosstalk 00:10:53] Jon: Yes. Please do. Female Speaker: Elm really enforces you to handle errors very specifically. In JavaScript, you can get [00:11:00] away with not writing the [.catch 00:11:02], whereas in Elm it literally enforces you to write a function how you handle the error, so that way you don't get crashes in runtime. Male Speaker: Okay. Female Speaker: Yeah. Male Speaker: That makes sense. Thank you. Jon: I wasn't kidding when I said interrupt. Please interrupt. Mm-hmm (affirmative)? Male Speaker 2: [inaudible 00:11:19] please? Jon: Yes. Oh, yes. Yeah. I'll come back to this. The reason it's so small is to show this here, this is not the code we're going to look at, but it's about 20 lines. I tend to have a lot [00:11:30] of padding. That is your entire Elm ... That's a basic Elm programme, we'll see. This is the entire code for it. This is the ... Yeah, you might add things to this, but this is all there is. I find it really simple. This bit, from here to here, that's your HTML. There is no HTML file for this code. It's all in there. Anyway. This is some Elm here to ... It's actually, in one function, making multiple calls [00:12:00] to the Flickr API. Oh, hang on. Let me show the code. Male Speaker: [inaudible 00:12:09] Jon: I can, then we'll lose this bit from the side. Oh, yeah. Let me just show pretty pictures. Male Speaker: Okay. Jon: There we are. This is the code. Yeah, I don't know what that is. [00:12:30] That really is what you get. I'm just getting back from ... Let me see. Ah, farm. Farm will give me something. There we are. And actually, in a way, yeah, we can see how the code ... Because the code isn't always getting results here. All right. Okay. So let me see [00:13:00] ... Oh, see, if I ... Yeah, actually ... Yeah, we're losing a bit from the right hand side. Yeah, that's about it. Everything fits in there. Actually it was great to dive into code early. Now ... Oh, actually ... Yeah. Let's get an event. Why not? One of my beefs [00:13:30] with Elm is about tasks. This is, hopefully, tasks, and it's really great. It's really powerful, but the documentation ... All right, to be fair, this is supposed to be a slightly harder thing to do, but it shouldn't be that hard. It's like the documentation has just been missing on it for months, and it's actually circular. One bit of the documentation, the guide points you to the packages, and the packages point you back to the guide. It's like, "Ah!" [00:14:00] But, yeah. That's one of my beefs with Elm. To get us all working on this, yeah. The documentation, it's nice for [inaudible 00:14:10] star, which is great, but try not to have gaps, and whatever. Anyway. What we're doing, we've got two HTTP.gets, obviously. I guess it's like glue bits. The first one is doing a search, and over on the right, the reason that's tabbed over [00:14:30] is to try and sort of make clear what's going on. The first thing gets back a photoList. Actually, if I scroll down, that sort of ... Yeah. Actually, it's not bad. If this is the photoList function, you're basically saying something about the thing that says, "Find photos, and photo, and just get something with this ID, and that field." You're very much saying, "It's got to have those, and if it's got those, [00:15:00] it's good," and if it doesn't have those, you won't get anything. It'll just ignore it. Does that make reasonable sense? Am I putting that across reasonably okay? Male Speaker: Could we just see the bit where it's ignoring it? Jon: Well, in a way, that is it, you see. Male Speaker: What you were saying about you have to handle the error case, where is that being handled? Oh, I see it now. Jon: Well, in a way, but you don't have ... Basically, this onError, here, we've got two get things going on, so [00:15:30] that first thing ... Let's quickly talk through the happy path, maybe, or ... It's funny, I thought I said that. That's the first time I've ever said the word happy path. So that's good. Laughter is good. But yeah, if we just talk to it working, and then imagine what would happen if it doesn't. So the first thing, it gets back a list of photos from [00:16:00] the JSON, whatever JSON data's come in. The next thing it does ... So that's almost like what task one ... The next task is to select a photo. There's not much actually going in there. It's really just getting the first item in the list. From then, given some specific photo, it then executes another get, which is, I think, to sort of request specific sizes that image exists in, something like that. That gives back a sizeList. [00:16:30] Then, pretty much the final thing is, you can't really see it, but we pass in some dimensions, the window size. So it says, "Well, find me the size that most matches that." So we've actually got a series of steps. Both the HTTP and the get ones can fail. If it all works, you end up with one specific photo that then is displayed. Also, yeah, this will have failed. Either failed or returned zero. [00:17:00] I actually took some code out of here, because it gets too confusing. I actually had some code that deliberately just randomly made the get process break, either first here ... And Elm just sails over it, sort of thing. So what happens in case of error? If the first one fails, it jumps straight ... Well, it doesn't quite jump straight, but it kind of falls through to this error here. If the first one succeeds, but the second one fails, again, it falls [00:17:30] through to that. That really covers it. That is your error checking. Again, it's perhaps declarative in ... Actually, yeah. That's perhaps where we get the idea being declarative, where rather than saying how to do it, where we had that ... Oh, there's the type for the photo we just Ided, and title. We declare what we want. We're not really saying how to get it, or how to ... So we're saying, [00:18:00] "This is what we expect." This says, "Go and get some of that." If it doesn't get some of that, then it just returns an error, and you're basically ... Also, with Elm, Elm forces you to handle all of the cases. So if you're making a HTTP request, you have to have some code, however basic, that handles the error case as well as the happy path. So that kind of is your error handling. You state [00:18:30] what you want. If you don't get it, you'll get something, yeah, a tidy error back, and it won't try and do things ... It won't go and access this second thing. Not that that would cause any harm, but it won't access the second thing, it just falls through. Does that help? Male Speaker: Very much. Thank you. Jon: Oh, okay. With everyone else ... It's like jumping into a sort of relatively complex bit of ... Female Speaker: What are the tasks about? Jon: Tasks are ... [00:19:00] It's hard to say, because they don't document them, but that's me having [inaudible 00:19:07], but I try and be honest about Elm, because I do know there's a lot of talk about Elm, and people say, "Oh, it's so great." I think, "Oh, I wish I inspired people like that." I feel so inspired by the thing. But then they sort of say at the end, "Oh, it's a functional language. It can be a bit hard," or something, and like, "Bye." I try and be honest about how it feels, and sometimes I really, really enjoy it, and I'm really in the flow with it, and it's so great. [00:19:30] Other times, either the language or the lack of documentation, it drives me nuts. And tasking ... Task is where you define, not an asynchronous thing, but you are defining something, I guess, that can ... Usually something that can fail. Is it necessarily asynchronous? It might usually be asynchronous. [00:20:00] That's not, perhaps, a very helpful answer. It's a good question. Female Speaker: When I'm writing Elm, I never use tasks because they're undocumented, and I don't understand them, so I'm trying to get around them. It seems like they are quite critical to your code. Jon: Oh, yeah. Please. Male Speaker: Can I give it a shot? Jon: Yeah, go ahead. Male Speaker: Okay. I apologise. The point of a task is to, yeah, to trigger an event that isn't ... The result doesn't happen now. It happens later. [00:20:30] The only way you can get an output from results ... And you haven't talked about the whole event loop thing, so this is going to make no sense until later. Jon will explain what event loops are in the future, I think. [crosstalk 00:20:42] So, just for now- Jon: ... that was too small. But this is fine. Male Speaker: The only way you can get something out of a task, or anything else that has either a side effect or is asynchronous ... Side effect meaning something where it doesn't happen in the confines of your programme, [00:21:00] so like talking to the web. You can only get an output from a task through that event, which means it gets fed into the same update loop as everything else. Now, that makes no sense, but remember that for when he explains event loops. Male Speaker 2: Have you just created a task? Male Speaker: Yes. Yeah. Sure. You'll be able to handle it later, and maybe it'll have an exception. Jon: Okay, so that says Front End London. This is a very basic Elm app. What's happening here [00:21:30] is just showing us the ... It's reflecting what we are about to type in, and it makes some stuff uppercase, other stuff lowercase, others just as we type in. If I just type in that, then do uppercase ... So, yeah. Very basic programme, although it's actually quite nice and simple to write this in Elm, because of unidirectional pattern. If we quickly go to the code, if we shrink this again, [00:22:00] just so we can see it ... Again, this is the total code there is. All that ... Yeah ... Actually, what do people think? For a framework, is that a lot of code, or not very much code? Female Speaker: [inaudible 00:22:15] Jon: Okay. Male Speaker: [inaudible 00:22:17] all right? Jon: Hm? Male Speaker: The framework itself, [inaudible 00:22:19]? Jon: Yeah, but that's compiled away. I mean, oh yeah, the download size, but that is the complete code, or- Male Speaker: I'm not going to argue with you, all [00:22:30] right. Jon: No, no, no. Sort of ... Yeah, yeah, yeah. That is all the code. I'll make it bigger, and I'll very quickly go through it. Up at the top we have the model. Model's very important. Model here is simply the string. We define events, which is these messages thing. This is boilerplate, to glue everything together. Subscriptions would be if we were getting any external things coming in. We're not. Then we've got the two main things of Elm ... Well, actually we've got the [00:23:00] initialModelState there. It says "hello, Front End London." We have the view, which is the HTML and the updateModel. It uses this ... Basically, once it's kicked off, these are the two main functions you care about. You have the unidirectional model, very much like Redux, like a lot of things these days. Basically, any time you type a letter, or any ... In this case, just typing a letter, but any input, it comes into the model, and what you get is that one single [00:23:30] change to your programme, whether it's a button click ... You only ever get one thing at a time. Again, it makes it so easy to reason about things. That comes in ... Anyway, once it processes what's come in, and that gets kicked off to the view, and the view just takes the model again, and says, "Well, from that I'm giving you this output." Underneath the virtual DOM, decides whether it's worth bothering to change anything. You just get that loop over and over, and that's your Elm programme. Okay. [00:24:00] Right. Over to questions, or have I used up my Q&A time? Male Speaker: No, everyone please put your hands together for Jon. Jon: Oh. Male Speaker 2: Okay. So the way that you're creating the HTML- Jon: Yes. Male Speaker 2: ... I find impossible to reason about, or understand. Is there something like JSX for Elm? Jon: [00:24:30] Not really. Also, what's going on here is this is actually code. It's- Male Speaker 2: I- Jon: Yeah, yeah, yeah. You can ... But since it's code, you can write your own wrappers for things. Yeah. If you think that looks horrible, I mean, here, and again, to keep it basic, I've said two line breaks and some text. I mean, I could put that into a function. Male Speaker 2: Sure. I can read it. I'm just not sure I'd be effective at writing it. Jon: [00:25:00] If I ... It's not ... Won't be helpful ... Oh, but it's pretty. Here, actually, the stuff on the left hand side, that's all built with Elm with that syntax that we're not happy with. This here is just D3 in, but that's fine. D3, again, we're introducing ideas. This is D3 in JavaScript. Pure JavaScript. We can, yeah, bring in JavaScript components, or just HTML. Here, Elm [00:25:30] is included. It's just still doing most of the button lifting, and things like that. It's just this bit. But you can have ... As soon as you bring in stuff that's non-Elm, though, you run the risk of, yeah, your code breaking, because if the JavaScript goes down ... This here is like a very self contained component. It's actually only got some data coming in. Not interested in what comes out. Yeah. This was where the demo happens, but I'm actually happy that this bit [00:26:00] is safe enough, because it's so little happening to it. Once you introduce any JavaScript in, you'd run the risk, if it goes down, it'll take the Elm with it. But, yeah, to go back to the code, yeah. It does look very strange. I mean, I find it works well if you ... Does it really look that strange? It's weird, because I've been looking at it for two years, now, and you sort of ... But, actually, [00:26:30] I think this is a big thing about Elm that the people proposing it don't always get. In a way, this is one of the bits I have the least trouble with, but they don't always get how difficult it can be. A lot of them come from a Haskell background. I remember, actually, I was sitting there when you were talking to Richard Feldman, who's one of the main people [00:27:00] involved with Elm, and I think your point was almost, to him ... You expressed it better than me. You were saying that it's almost Elm's time, and if Elm doesn't really push now to get itself fully accepted, and people using it, that time may pass. I think that is a bit of an issue with it. I'm not sure the people who were hired at Elm are always addressing that. They need to overcome things like that. For me, [00:27:30] it doesn't work ... I found, using it, I get reasonably familiar with it, and I just wrap certain things, and I make little components and functions. I do love the fact that because it's a function, all my HTML is compiled wherever I pass to it, if I forget a function. It's so nice. It's resilient. I'm actually- Male Speaker 2: I guess the point I'm making is that when I look at that, [00:28:00] I'm having to do the job of compilation myself to be able to turn it into the mark up. That doesn't feel like a comfortable place to be when I'm doing something even more complicated than making things upper and lowercase. Jon: Yeah. Male Speaker 2: Right now we're just separating strings of text with breaks, and nothing could be simpler about this code, yet it seems strangely obtuse. I've been spoiled by HTML and by things that look like HTML, but actually [00:28:30] have [inaudible 00:28:30] because they turn into functions [crosstalk 00:28:31]. This doesn't feel like that. Jon: There may be ... Toss out there, to take ... I mean, one sort of thing that functional programmes do very well, they may well be tossed out there to take your JSX and create Elm code out of it. Male Speaker: I really like that philosophical point about now is Elm's time, and unless they make the most of it ... It could be a really good idea that sort of doesn't see [00:29:00] the limelight. Maybe it's going to take something like that to really kind of push it forward, in the same way that React has been. I think this has been an excellent talk, Jon. Thank you very much, and thanks for giving this intro. Could you guys please put your hands together for Jon?