This interview was recorded for the GOTO Book Club.
Richard Feldman - Author of "Elm in Action"
Thomas Anagrius - Lead Developer at Humio
The interview is based on Richard Feldman's new book "Elm in Action": https://www.manning.com/books/elm-in-action?a_aid=trifork&a_bid=a11d59e7
Read the full transcription of the interview here:
Looking for a unique learning experience?
Attend the next GOTO conference near you! Get your ticket at https://gotopia.tech
SUBSCRIBE TO OUR YOUTUBE CHANNEL - new videos posted almost daily.
Looking for a unique learning experience?
Attend the next GOTO conference near you! Get your ticket: gotopia.tech
SUBSCRIBE TO OUR YOUTUBE CHANNEL - new videos posted almost daily
What is Elm?
Preben Thorø: What is Elm?
Will Elm take over the world?
Preben Thorø: Feeling that popularity has just been increasing. Will Elm eventually take over the world?
Thomas Angarius: Well, maybe comparing it to Python is not the best comparison either, right? Because that's a general programming language, whereas Elm is a functional language. I think that's, really, one of the big strengths for Elm is that it was tailored to doing web applications, right?
Richard Feldman: That's very true.
Thomas Angarius: So, I think you're right. I don't think Elm is going to take over the world, either. I think that it's a somewhat niche language.
Richard Feldman: It's focused.
Thomas Angarius: It's very focused and it's very deliberate and it's very opinionated in how it does things. And I think the very popular things that you see out there are more general, right?
Richard Feldman: Yes, they have a similar or broader scope.
Move away from the dependency nightmare
Thomas Angarius: Definitely, I mean, one of the things that struck me a couple of months ago is that at Humio, we have a codebase of, you know, 100,000 plus 200,000 lines of Elm code and we have, like, 12 dependencies, some of them, like, Elm tests, for instance, right?
Richard Feldman: Nice, nice.
Richard Feldman: Yes.
Thomas Angarius: And, I mean, personally, you know, when things go wrong or when I start to hack in my code is usually because I need to hack around something that comes from a dependency, right? So, when it's your own code, you don't really need to do that. And, sure, it's a little bit more effort, but in the long run, it's worth it, right?
Why does Elm seem so hard for beginners?
Thomas Angarius: I think it might also be one of the things that's a little bit scary about Elm for new people. Like, I often encounter people when they're just starting out, like, why is everything so hard? Of course, I don't think they're so hard.
Richard Feldman: If something's new, then, you know, of course, it's unfamiliar. It's by definition harder than what you were doing before.
Thomas Angarius: Yes, but I think there's more than that though, right? Elm is a very, as I said before, opinionated in how it does things. And it's very restrictive. You can't just go out and touch the DOM, right?
Richard Feldman: True.
Thomas Angarius: So, in the book, you take people from learning the basic syntax, because it is not a seed family language, right? So, the syntax is quite, some would say exotic, some would say arching to what people are used to. And that can definitely be a factor as well.
Richard Feldman: I think it depends on your background.
Thomas Angarius: It's such a simple language at the same time, right?
Thomas Angarius: Oh yes, exactly. More of the way of interacting. That's what I meant, right? That you don't get to go out and touch the DOM. You do things in a very strict manner and very strict order.
Thomas Angarius: Right. It's about getting people to appreciate what those benefits give you, right?
Richard Feldman: Totally, yes.
Thomas Angarius: Which is hard to see when you're just starting out.
Richard Feldman: True.
Benefits of using Elm in a large organization
Thomas Angarius: When you reach a certain size, like at Humio, we're a lot of developers on a big codebase and I'm never afraid of breaking the codebase because I trust in the compiler. If it compiles it works. And that's a feeling, a sense of security you don't really see even in other strongly typed languages. Because they allow you to escape that safety, right?
Richard Feldman: Right, right.
Thomas Angarius: Elm really does not.
Richard Feldman: Yes, people ask me what's the difference between Elm and TypeScript? Is Elm a typed language? Well, TypeScript has types. What's the difference? And one of the easiest differences to point to and maybe the biggest one is any. In TypeScript, you have any, which is the escape hatch that means that any possible types could be alive. It's not achievable to have the same level of trust in TypeScript as you do in Elm. And that sounds like kind of an abstract thing. But, as you said, I mean the real benefit there is this feeling of invincibility of “I can make whatever change I want and once I get it to compile again,” it's probably going to work again. And I've gotten so spoiled by that. As you said, we have this huge codebase and we just make big changes to it whenever we want to. If we think that the code's going to be better if we reorganize it in a particular way, we just do it and then we follow the compilers until it works again.
And usually, we don't even need to change tests unless, you know, there are also corresponding type errors in the test. But it's not like we need to lean on handwritten tests to give us that same confidence. We do have tests, too but the compiler is 90% of what's getting us back there and we didn't even have to write that code. You know, the compiler just did it for us just because we were using Elm. And the amount of code cleanup that we can do so much faster has really been for me just something I can't imagine giving up again. The ability to just say I want to clean my code up in this way, I'll just do it and it'll be fine. Whereas even in other typed languages that I've used, in a lot of cases I'm, like, "Well, if I change it is it going to work again afterward? Am I going to cause a bunch of regressions?" I just never have that fear in Elm.
Thomas Angarius: Especially when it's someone else's code, right?
Richard Feldman: Oh yes, absolutely, right. We have almost 100 employees at NoRedInk where I work. That's not a huge number of people. There are obviously companies with thousands and thousands of employees. But, I don't know if any of my coworkers are even aware of the code that I'm writing, and I may not be aware of the code that they're writing. There are parts of the codebase that I haven't ever seen before. Maybe somebody is writing it while I'm having this conversation.
Benefits of functional languages
Thomas Angarius: That's a good point. In functional languages, one of the key differences I think is that what you see is what you get. What you're looking at right now is what's going to happen, right. You shouldn't be afraid of changing something in the invoicing part of the code and it all of a sudden breaks the carousel on the front page, right?
Richard Feldman: Right, right.
Thomas Angarius: Because of side effects. Because there are none when everything is a pure function, right. That is such a game-changer for large codebases, I think.
Richard Feldman: Absolutely. I usually don't mention that one when people ask about the difference between Elm and TypeScript because it's a little bit harder to explain. But, yes, I really felt that one when I have been comparing Elm and Rust. So, I've been spending time with Rust as well. I like it a lot. There's a lot of great things about Rust. But, the refactoring ability is just not on the same level as what I get in Elm. And, it's like you said, it's because of the side effects and mutation. Rust even has a first-class concept of mutation tracking and they don't have any which TypeScript does. And it was a typed language from day one. So, like, the whole ecosystem is, you know, typed.
So, in those ways, I would say Rust typed system is a lot more reliable to me than TypeScript's, but even with that, I've still had bugs where I took some Rust code, and I just habitually, because I can do this in Elm without any concern, I'll just rearrange the order in which things are happening. I'm, like, "Oh, actually, I think it makes more sense to, like, call this and then call this and then call this." Or I did some other refactor that resulted in code being in different places and it didn't work anymore afterward. It was broken. I was like, "Why? How could this have broken?" Because in Elm, you know, as you said, when you have the guarantee that functions don't have side-effects you really can just rearrange them however you want to make the code nicer and really have the full expectation that it's going to work again afterward. But even in Rust, that has not been true for me. I've definitely broken stuff just by reordering it. Whereas in Elm, you say let's reorder it. It's fine. If it compiles again, it's going to work. And it almost always does to almost a shocking degree. I mean, it's really ridiculous.
Thomas Angarius: You can still code the wrong thing, right. You can still code the wrong thing.
Richard Feldman: Of course, yes. It's not 100%. It's not possible to guarantee that if it compiles it just works. But it is just ridiculous how often it is. I mean, it's certainly most of the time. And it's, like, I don't know what exact percentage, but it feels like it's, like, in the 80% plus range. That, when it compiles I just expect it to work. And if it doesn't work I'm very surprised. I'm, like, "What happened? How did this compile and then not work?" Which is a hard feeling to convey because it sounds so ridiculous at face value. I mean, if you spend a lot of time programming in other languages that's not normal.
Thomas Angarius: One of the interesting things is that for our application whenever we have bugs, it's usually due to CSS because we don't use Elm-CSS. Maybe you can talk a little bit about what that is?
Richard Feldman: Oh sure. Elm-CSS is a library that I made. We use it at work. Although, honestly, I feel like every time I bring up Elm-CSS I need to make a plug for Elm-UI which I kind of wish we were using at work except that we just have so much legacy CSS it would be a really big project to convert to it. But, Elm-UI is one of the most beloved and, like most popular Elm packages, it was made by Matt Griffith and basically, it's a CSS alternative. Where, basically, it's a way to do layout in the browser without even knowing CSS. Like, you don't have to know any CSS concepts. No flexbox, no grid, no float, no any of that. It's just a complete ground up, a scratch rewrite of, like, a layout system that works in the browser.
But because we had a big React codebase before we started using Elm, we have Legacy CSS and, so, we sort of incrementally moved that over to Elm-CSS. It was originally styled-components, I think was the one in React. But, I think there are new names for it now. I think there's one that more closely resembles the Elm-CSS-UI or API. But, I forget what it's called. I want to say it's Emotion, but I might be misremembering that. I've been kind of out of the JS world for so long. I don't know the names of things anymore. But, the basic idea is that it gives you a way to do type-checked CSS in your front-end code, and also you don't need to have a separate style sheet.
So, I can basically just add an attribute to any of my HTML values, any of my elements that just have CSS, and then the CSS attribute takes a list of typed CSS properties. So, for example, if I want my button to have a one-pixel border, I can just say CSS and then square brackets, because you give it a list of all the attributes that you want. And I just say, like, you know, border one pixel solid, blah, blah, blah. And if I mess that up, like, if I mistype something in there then I'll get an error in compile time. And then it behind the scenes will automatically generate a class and then it's, like, a hash of all the styles in there and reference that and so on and so forth.
So, yes, it makes things a lot easier, but it is at the end of the day still fundamentally CSS. So, it's sort of a way to make CSS nicer. I counted it at some point. It's like 600 and some odd different typed CSS properties in there. So, it's not the entire 100% of the CSS spec, but, you know, it's a lot. And, yet, you know, I also think it's funny, whenever I see people complain about TypeScript compile times, I'm like, what's that? What's a long compile time?
Thomas Angarius: It's funny you said that because of one of the reasons, we went to have everything in Elm which is quite a big benefit, right? Thinking about your application is not just the behavior, but also the way it looks. Because you can't really separate the two, right, in a web application. But, at the time, which is now several years ago, the compile times were so excruciating long that it just wasn't feasible to, you know, when you want it to say how does this look when it has a rounded corner and you have to wait 80 seconds or something like that when you get to a certain size, right.
Richard Feldman: Yes, like, 2017 Elm compile times were not great. I think that was, like, everyone's favorite release of, like, the people who are using Elm today, but who were also using it in, like, 2017. Like, the one that just made the compiler ridiculously fast. Yes, that was a total game-changer.
Thomas Angarius: We went from, like, 2.8 minutes to 4 seconds.
Richard Feldman: Right, and that's, like, a scratch-build, right? The entire codebase in four seconds.. Because, like, incremental compile times are usually sub-second, but that was a nice release. Although, I guess, you know, getting back to the book, the amount of code that you end up writing in the book, even though it is one application, like, starting in… So, chapters 2 through 8 are all about building one application. So, like, chapter 1 is just basic syntax, but then throughout the rest of the book it's all about building an application from start to finish and then each chapter, like at the beginning, you get sort of feature requests from your manager. Then you implement that feature request over the course of the chapter. In the course of implementing that feature, you learn about the concepts necessary to do that. The entire time, I think, I guess I haven't tried it on, like, a Chromebook, but I would expect that all the compile times throughout the entire book would be less than a second. I would be surprised if someone's machine took more than a second to compile something.
What does the book "Elm in Action" help you with?
Richard Feldman: It's discouraged, yes.
Thomas Angarius: Why do you do it? We do it as well. Anyway, at and outside work.
Thomas Angarius: Yes, it's very much that feeling.
Modeling with the Elm Programming Language
Thomas Angarius: One of the biggest takeaways, I think, that I have from using Elm: if I were to never touch Elm again, and I still think I've benefited from being an Elm developer because, the focus or the way that I write Elm is that I start by modeling things, right. Really modeling the problem. And I don't think that I've ever done that in any other language or platform. And I wonder whether that's because of necessity or because… why that is?
Richard Feldman: That's a good point. Yes. Just like getting the data model right. Getting the data, yes.
Thomas Angarius: Like, in Elm, it is so beneficial to, you know, the famous phrase, "To make illegal state unrepresentable." But it's not just for Elm, right. It's something that… go into Java and you can do exactly the same thing and get exactly the same benefits. But, you just don't feel the pain as much if you don't do it. And I think that's because in Elm you have to handle every contingency. If your model allows you to both have a field that says that you got a server error in it, and another where it says, here's the successful data. Like, those two are incompatible.
Richard Feldman: Well, you've got to remember to handle the failure possibility.
Thomas Angarius: But if you have both of them, you deal with them being there.
Richard Feldman: Right. I think it's because the compiler tells you about edge cases. It's not, like, you find out about them, you know, way after the fact after it's, like, a bug report. You find out about it when the compiler tells you you didn't cover this case. Then, yes, I totally agree. I would say Rust is maybe the only other language where I've done that because Rust and Elm have similar typed system capabilities in terms of sum types and product types. But, yes, it's definitely changed the way that I've thought about programming, like, for the better. I definitely think that the way that I write Elm code is just more robust and better. The language sort of guided me to do that. I think that was just like a cultural phenomenon that people just decided to do. The experience of using the language just makes me move in that direction and it's a good direction, yes.
Preben Thorø: Thank you both for the conversation.
Richard Feldman: Thank you for the invitation.
Thomas Angarius: Thank you.