Check out a free preview of the full Introduction to Elm, v2 course
The "Virtual DOM" Lesson is part of the full, Introduction to Elm, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Richard explains that Elm uses a Virtual DOM for rendering - the same underlying approach React uses. However, Elm does it with plain function calls instead of templates.
Transcript from the "Virtual DOM" Lesson
[00:00:00]
>> Richard Feldman: So to recap, this what we're gonna be building. This thing called Conduit, this medium clone. And the way that we're gonna be doing this is by using the virtual DOM. The virtual DOM is something that is popularized by React. And it's something that elm uses as its fundamental way of rendering things.
[00:00:18]
So whereas in JavaScript, you can opt into a virtual DOM by using something like React or any of the virtual DOM systems out there. But in Elm, it's the only way to do it. All there is a is a virtual DOM. That is the fundamental primitive of rendering in Elm.
[00:00:30]
So what do we mean by the DOM? So the DOM is the Document Object Model. This is some HTML. HTML, the Hypertext Markup Language, is a representation of the DOM. It's syntax that describes a particular structure. So here we have an unordered list. It's got a class of languages.
[00:00:46]
It's got two li's inside of it. One is Elm the other is JS. This HTML describes this DOM structure. So at the root, we have root node that's a ul. It's got a class attribute of languages. Then it's got two child nodes. One is an Li, another is a different Li.
[00:01:06]
Actually each of those Li's also has a child node, a text node. So one is a text node called Elm has element. There was a text node that has JS in it. I'm gonna be honest with you, for most of my career, I did not know the text nodes existed, I thought they were just magical strings.
[00:01:22]
Turns out the DOM nodes, I just didn't know that for a long time. So this HTML, in the upper left, describes this DOM tree on the right that's going to actually exist in the browser's memory. But there are lots of different ways we can represent this DOM tree.
[00:01:37]
We don't have to use HTML to do that, in fact Elm doesn't use HTML to do that. Elm just uses plain function calls. So, here's how we could represent this in Elm. So, we have a function called UL. It's being passed two arguments. The first is a list of attributes.
[00:01:54]
In this case, we have only one attribute, class languages. And then a list of child nodes. So, in this case we have two child nodes, both of them are Li's. Each of the Li's has a list of attributes. But these don't have any attributes unlike the ul, so they're just empty lists.
[00:02:08]
And then they also have a list of child nodes. And in this case both of them have a text node for their child nodes. So Elm just uses plain function calls for all of these. And because Elm uses whitespace for function applications instead of parenthesis. We can see that this has pretty visually similar structure to the underlying DOM, and also a pretty similar structure to the HTML up here.
[00:02:33]
So Elm doesn't really need a separate templating language for this, because we can get something, a little DSL that looks pretty similar, just by writing clean Elm code and normal function calls. A little piece of trivia, this is actually how React was originally designed. Jordan Walke, when he originally made React, he just used it with plain function calls.
[00:02:50]
But at Facebook, they had been doing a lot of PHP templating on the server side. And when he made the first pull request to introduce it to the company, people were this is weird, we wanna see our PHP looking templates. So he actually invented jsx in order to solve that problem and to get his pull request accepted.
[00:03:06]
So he changed it from plain function calls to a template. And that's become the norm in a lot of virtual DOM systems, whereas Elm in some sense goes back to the roots and says fundamentally the big idea here is functions. We're just gonna use plain function calls to describe the stuff, and that's how our whole code base at work works.
[00:03:24]
That's how all Elm code bases work, nothing more than plain function calls to describe these things. So the one syntactic note has to do with position of the commas here. So this is not quite idiomatic Elm code. The way that you would idiomatically write this is with the comma on the left here.
[00:03:42]
The first time I saw this, I thought, that looks weird, I'm not gonna do it that way, I'm gonna do it a different way. And then I realized the benefit of doing it this way, and I switched, and then got used to it, and subsequently think, okay, yeah, this way actually is better.
[00:03:55]
So let me explain the problem that this solves. So let's say that I have the comma on the end here, and this is more typically how it looks in JavaScript. The problem is, what happens if I forget that comma, if I leave it off, accidentally just left it off.
[00:04:13]
And I've definitively done this before. What is actually happening here? What is this code now do that's different from what it did before? Well previously what we had was we had this is a function called Li passing two arguments. And then this is a function called Li passing two arguments.
[00:04:30]
They're separated by a comma because there are two elements on the list. This one doesn't do that anymore. In this one, we're gonna get a compile error that says you are passing five arguments to Li. And you might be no I'm not, what are you talking about? I'm passing two arguments to Li, twice.
[00:04:46]
But actually, without the comma there, this error accurately represents what's going on. We have Li, passing one argument, two arguments. There's no comma so we're just gonna keep going. It's just more whitespace. Three arguments, four arguments, five arguments to Li. So getting this error message is kind of confusing because it seems to be just wrong.
[00:05:06]
It seems you are passing all these arguments and it's no I'm not, I'm looking at the code it looks fine. Especially if you have a particularly long, complicated expression it can be a really confusing error to get. But if you have this, instead we have the comma on the left now we have this vertical line.
[00:05:29]
This column of characters, that makes it really, really obvious if you leave the comma out. And this works, no matter how many things you add to the list. You can just keep adding to the list, and keep adding commas. And if you ever forget one of these commas, it's immediately, blindingly obvious, that there's something missing there.
[00:05:48]
So I reluctantly tried switching to this style and then realized that, I just never, ever got that error ever again, and I was, okay, that's worth it. The first time I was pair programming with somebody at work and they got that error and were confused by it. I was okay, yeah, we're switching, we're gonna do it this way.
[00:06:03]
And today we have Elm Format which is a code formatting tool that something 90% of Elm developers, I think it's actually over 90%. It's really ubiquitously used. It's a prettier or go/format or gofump, I believe they pronounce it in other languages. Where essentially the idea is to enforce a common syntax across all Elm programs and it will do it like this.
[00:06:28]
Also worth nothing that Elm format is unique, as far as I know, among front end code formatters in that it has no configuration options at all by design. It cannot be configured in any way. And that's a design goal because it prevents style arguments. It means that you can't get into an argument about what you should configure it about, what should go where.
[00:06:49]
Because there just aren't any configuration options, it's pretty nice. So to recap the things we've talked about in Part 1. First we talked about compiling, so running Elm make, passing Main.elm, which is our source file. And then output of elm.js, which is the .js file that we're ultimately going to give to the browser using a script tag in index.html.
[00:07:08]
Talked about functions and how to define them and also how to call them. So when we call them passing, for example, pluralize "leaf" "leaves" 1. We don't use comas and we don't use parenthesis. If we do use parenthesis it's only to disambiguate between nested expressions. Not because function calling actually needs any parenthesis.
[00:07:25]
Talked about if expressions, so if quantity == 1 then. We talked about how in Elm you use double equals instead of triple equals, we have then instead of curly braces. Else is required because if is an expression. So you can pick it up and move it in different places, assign the result to a value just like a JavaScript ternary.
[00:07:43]
And finally, we talked about the virtual DOM and how, in Elm, virtual DOM is done using plain function calls. So Li passing a list of attributes and also a list of child nodes. We also talked about how text nodes in Elm are represented by a function called text.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops