Check out a free preview of the full Introduction to Elm, v2 course:
The "Smart Compile Errors" 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 demonstrates how the type inference build into the language can benefit the user by catching errors before the code compiles.

Get Unlimited Access Now

Transcript from the "Smart Compile Errors" Lesson

>> Richard Feldman: So we've seen this different syntax, but we haven't really seen what the benefit is. So so far we've seen some of the costs of Elm, you have to learn a new syntax, but we haven't really seen any of the benefits yet. So let's talk about those briefly.

[00:00:11] So in JavaScript let's say we write our pluralized function, and we say pluralize "leaf", "leaves" in one, it works out. If we say pluralize "leaf", "leaves" in 3 it again gives us the correct answer, but now let's see we make a mistake. So instead of returning singular, we return singula.

[00:00:26] That's a mistake. Singula is not a thing. That doesn't exist. So, what's gonna happen if we do this? Well, if say pluralize leaf leaves in 3, nothing's gonna happen. It's still gonna work because by coincidence we didn't happen the traverse the path that led to the bug. If, on the other hand, we say pluralized leaf leaves in one, it's not gonna work.

[00:00:45] What's gonna happen is we're gonna get a runtime exception. Uncaught reference error. Singula is not defined. Which, yeah, okay, fair enough. Indeed it is not defined. So this would be an example of a crash. Not really what we want to give our users in terms of user experience.

[00:00:58] Now typescript will do a little bit better than that. If in typescript if we write the same code, we'll get an error. So error TS2552, cannot find name singula, did you mean singular? So, it identifies at compile time, this is a mistake you made. I know that there's nothing named singula in scope here, so you need to fix that before we will compile the program and actually run it.

[00:01:21] How about Elm? If we make the same mistake in Elm, we say singula instead of singular in the first branch of our if. Similar kind of thing. Cannot find variables singular, maybe you want one of the following singular. So again this is much like type script Elm is able to catch this at compile time and prevent that run time exception.

[00:01:39] Okay let's look at a different error. Let's say in JavaScript say if quantity triple equals the string one. Now when we say pluralize leaf leaves in three, it still works. Pluralize leaf leaves in 1 now it's back to the original broken case where things are not working properly anymore.

[00:01:55] So these is also not what we want, the whole reason we wrote these function was to avoid these edge case bug from happening. And here we've made a mistake that is still going to result in that bug being present, okay. So the root of that problem by the way is that one, the string one, when compared with triple equals to the number one returns false.

[00:02:16] Those are not considered to be the same thing in JavaScript. And in Typescript, same thing. This will compile, this will run, it just won't work properly. We will still has this bug materialize at runtime. What about a Elm? With Elm, this actually won't compile. It'll say, the 3rd argument to function pluralize is causing a mismatch.

[00:02:36] That is to say, when we're calling pluralize up here, the 3rd argument is causing a mismatch. Function pluralize is expecting the 3rd argument to be a string, but it is a number. So essentially Elm was able to figure out, you know what this is gonna be a bug.

[00:02:49] If we write this expression, this is always going to fail. Something is off there. I'm gonna tell you about it at compile time and ask that you fix it before you actually run this application. The way that Elm's able to do this is using what's called type inference.

[00:03:01] So it essentially knows about all the types that are in your program. By doing a process of sorting of with some facts that it knows, one is a number, leaves is a string and then going through and figuring out implications of those facts, so it says okay. While seated, you're comparing quantity to a string.

[00:03:17] Which means quantity must be string, but here I see that you're calling it passing 1 for quantity which is a number. So how can it be both a string and number? Something is off, I'm gonna tell you about that. That's an error of compile time. Elm does type inference across everything.

[00:03:31] And I do mean everything. So there's no any type like there is in TypeScript. There's no escape hatch where you can say, trust me, I know what I'm doing. Elm's compiler really does do type inference across 100% of every single value in your entire Elm program, and all of the packages in the entire ecosystem.

[00:03:48] This is how we're able to avoid runtime exceptions. Fundamentally, it's the combination of Elm's insistence on doing type inference across absolutely everything. And the way that the libraries are designed, which we'll learn about through the course of the workshop. This prevents this from happening. So yes, there is some new syntax to learn.

[00:04:04] There is some different concepts to master. But ultimately, the guarantees that this provides, and the reliability that results from that is a pretty serious benefit.