> ## Content Index
> Fetch the complete content index at: https://madewithlove.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# A nice app on Elm street
- URL: https://madewithlove.com/blog/using-elm-with-react-a-nice-app-on-elm-street/
- Published: 2019-09-15T16:52:03.000Z
- Updated: 2026-05-29T11:58:08.000Z
- Author: Emma Fabre
- Tags: Engineering, Tutorials, JavaScript, Frontend

If you’ve ever worked with Redux – in the context of a React application or not – you may have heard numerous times that it was inspired not only by Flux (which it followed) but also by the Elm architecture. This is something that is thrown around a lot by people in the React ecosystem, and looking at the Elm homepage it may seem difficult to see the link between a strictly-typed language and a JS state management library.

## Quick menu

- What is Elm
- Setup
- First contact with Elm
- I want to get off Mr. REPL’s wild ride
- Setting up our web application
- Compiling our application
- The Elm architecture
- Setting up a build system
- Setting up a basic Webpack build
- Setting up hot reloading
- Advanced messaging and user input
- Elm: The Conclusion
- The Good Stuff
- The Maybe Not As Good Stuff
- The Subjective Median Opinion of the Stuff
- Would you like to know more?

## What is Elm?

Elm is both a language and an architecture – it is a functional, compiled to JS, strictly-typed, immutable and pure, opinionated language to build web applications. Part of the language’s opinion is that your application should be structured a very precise way, which we call the Elm architecture. It is a very fascinating language with a pretty long list of benefits, to only cite a few:

- **No runtime exceptions**. Now that does not mean that there will never be any bugs in your application but the compiler is one of the best compilers I’ve ever seen and will not compile if it detects that your code is not sound. If you’re familiar with Javascript and having dozens of random errors in your console or that only happen on edge cases, this is the main benefit for me and one that way outweighs any cons of the language.
- **Great performance**: Elm is fast, *very* fast, and it is so *by default*, there’s no pattern to know, or optimizations techniques to learn, it is fast because it does an incredible amount of optimizations underneath (as is often the case with strictly-typed languages, because they have more informations on what you do).
- Elm puts emphasis on being **explicit and avoiding the unknown**. And this has ramifications throughout everything. A simple example: [Semver](http://semver.org/) is strictly enforced on all packages. What that means is that people don’t “really” version their packages: instead, the package manager analyzes what changed in the codebase and tags new versions itself. As a package consumer, you can then easily upgrade your dependencies as Elm will show you a summary of the API changes and what you need to change in *your* codebase.

And that’s just barely scratching the surface. It is the work of [Evan Czaplicki](https://github.com/evancz) from NoRedInk, which is quite amazing considering he works on it alone.

So if you’re tempted to take a crash course in Elm programming, then keep reading. Even if you do not intend to use it as a language, it contains interesting ideas that could still help you shape your applications, no matter the language you’ll write them in.

In this article we’re going to build a (somewhat) small application with Elm, learn piece by piece how it works and what the Elm architecture is, and to conclude we’ll draw some parallels with your usual Redux application.

## Setup

First things first, let’s install some stuff. Let’s start by checking that we have the correct version of things. We’ll need Node and NPM (or Yarn if you’re cool):

```bash
$ node --version
v10.5.0

$ npm --version
6.1.0
```

Once this is done, let’s initialize a Node project in an empty folder, by doing `npm init --yes` to create a `package.json`.

Now that we have a standard setup, let’s install Elm. The easiest way to do so, is to simply run `npm install elm --save`, and then do `elm --version` to check that it properly worked:

```
$ elm --version
0.18.0
```

If you type `elm`, you will notice that the binary is actually a placeholder for the whole Elm platform, which means you will actually never call `elm` itself but the tools it exposes (eg. `elm package install`, `elm make`, etc.).

> Note: the binaries will be placed in `node_modules/.bin`. If you don’t have it in your $PATH it is recommended to do so. The rest of this article will not use the full paths to each binaries but call them directly instead

---

## First contact with Elm

### Primitives

One of the things in the Elm tool belt is a REPL: an interactive console in which you can play with the language. So let’s fire it up and learn the core syntax of the language a bit. You launch the REPL by calling `elm repl`, and you quit it by typing `:quit`. Since this is our first contact, let’s just review some primitives and see how it goes.

The most basic types in Elm, as in most languages, are strings and numbers. If we type “foobar” (double quotes only) in the REPL this is what we get:

```
> "foobar"
"foobar" : String
```

As you can see, we gave Elm a string, and it returned something in the form of `x : y`. This is a type annotation, this is how you declare *what* things are in Elm. In this case, Elm saw `"foobar"` and basically said “That’s a string”.

If we try with a number we get the same result:

```
> 5
5 : number
```

Here we typed 5 and it said “This is a number”. Note that `number` is lowercased because it is an alias for “Either a `Float` or an `Int`“. As mentioned before, Elm is *strictly-typed* as opposed to the language it compiles to (Javascript) which is loosely typed.

If you’re unsure what that signifies, it means that in Javascript the engine **guesses** your intentions and will let you do whatever you want on the basis that it can never be sure of them. If you want to try to do `{foo: "bar"} + 2` it’ll trust your judgement and just let you do it, even though it does not *make sense* or might crash your app. Whereas in a strictly-typed language, you usually have to declare *what* things are and what they do and the engine will not let you do things that do not make sense in the context of what you’ve declared. As a small example of what that means, and try to add a number to a string:

```
> "foo" + 3
-- TYPE MISMATCH
The left argument of (+) is causing a type mismatch.

4|   "foo" + 3
     ^^^^^
(+) is expecting the left argument to be a:

    number

But the left argument is:

    String
```

As you can see, we tried to do something that the compiler thought didn’t make sense, and it prevented us to. All good. Let’s proceed and declare our first function:

```elm
> add x y = x + y
<function> : number -> number -> number
```

This piece of code is most likely going to be confusing in some aspects so let’s break down some of the confusion:

- First: Elm does not have any variable or function declaration keyword (like `const`, `function` or `let`), you simply write `someFunction = its contents` or `userAge = 3` and Elm will know what you meant and scope everything nicely.
- Second: returns are implicit, you never type `return XXX`, because *everything you do* returns something. This is part of the fact that in Elm all things are immutable: you never modify an object or a variable, you simply create a new “version” of it with a new value. If you’ve had to fight with references in JS or were forced to use `immutable.js` and such to avoid your app behaving madly, this is already a huge relief in itself.
- Third, you won’t use parenthesis in Elm in most of the places you’d use them in Javascript. They still have their standard use, but we just need them a lot less. Per example if we wanted to call our function, instead of doing `add(1, 2)` we’d simply do `add 1 2`:

```
> add 1 2
3 : number
```

Finally, Elm returned what it thinks the type of our function is and it properly guessed that we were expecting numbers. How? Because operators do not work the same in Elm as they do in Javascript.

In JS, operators are reused between types, what I mean by this is that you can do `5 + 5` but you can also do `"foo" + "bar"`. In Elm, each type has its own operators, so you’d still do `5 + 5` but you’d do `"foo" ++ "bar"`. The reason is that in Elm (as in a lot of functional languages) operators are functions as well (infix functions to be precise) and `+` is just a function expecting two numbers, and not strings, whereas `++` is a different function that expects strings, not numbers.

If you looks closely at the type annotation of our `add` function, you notice a new operator, `->`, it’s used to demonstrate arguments and return values. If per example we had a function that took two strings and returned a number we’d have `String -> String -> Int`. You may wonder why the same operator is used for arguments **and** return types, and it’s quite simple: in Elm, absolutely *all* functions are curried by default. If you’re not familiar with currying, first of all no relation to the indian dish, second of all here is the definition for it:

> In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument

You may have encountered it a lot of times in Javascript without being aware of it. Per example here is a curried function:

```javascript
function add(firstNumber) {
  return function with(secondNumber) {
    return firstNumber + secondNumber;
  }
}

// Or with short arrow syntax in modern versions of ES
// const addWith = firstNumber => secondNumber => firstNumber + secondNumber

const addWithTree = add(3);
addWithTree(5) // 8
add(3)(5) // 8
```

Basically instead of having a function taking arguments A B C, you have a function taking an argument A, returning a function taking argument B, returning a function taking argument C, returning the result. In Elm, this is the default behavior of all functions, let’s try it with our basic `add` function:

```elm
> add 1
<function> : number -> number
```

Here we only specified one of the arguments of our function, and what we got back as we can see in the return type, is now a function that accepts **one** number, and returns another number (the result):

```elm
> addWithOne = add 1
<function> : number -> number

> addWithOne 2
3 : number
```

This is the reason why arguments and return types both use the same operators: because Elm does not make the distinction.

### Arrays (Lists)

Arrays (called Lists in Elm) work pretty much the same way in Javascript with one difference since we’re in typeland here: an array can only hold values of the same type. That is to say you never *just* have a list, you have a list *of something*:

```elm
> [1, 2]
[1,2] : List number

> [1, "foo"]
-- TYPE MISMATCH

The 1st and 2nd entries in this list are different types of values.

5|   [1, "foo"]
         ^^^^^
The 1st entry has this type:

    number

But the 2nd is:

    String
```

Other difference with Javascript: types are *not* objects, so you won’t be able to do `[1, 2].length`. Instead, you’d call the `List.length` method, *on* the list. Same is true for all the functions you’re used to (map, filter, etc)

```elm
> someArray = [1, 2]
[1,2] : List number

> List.length someArray
2 : Int

> double someNumber = someNumber * 2
<function> : number -> number

> List.map double someArray
[2,4] : List number
```

That doesn’t mean that this is the only way to do things as Elm supports a good bunch of function composition/applications operators, but we’ll see that later on, don’t worry about it.

### Objects (Records)

Now that’s fine and all but if you’re coming from Javascript then you know that objects is where it’s at, so let’s create an object (called **Record** in Elm). The syntax is slightly different but familiar enough that you shouldn’t get lost:

```elm
> myObject = {foo = "bar", baz = 5}
{ foo = "bar", baz = 5 } : { baz : number, foo : String }
```

Only difference with JS is that we use `=` instead of `:` (since `:` is for type annotations) but apart from that, standard rules apply, so you can call `myObject.foo` and you will get `"bar"` as you’d expect. There is however one tiny but useful difference: the dot operator is *also* a function (like everything in Elm):

```elm
> myObject.foo
"bar" : String

> .foo
<function> : { b | foo : a } -> a
```

If we call `.foo` by itself, Elm creates a function that will accept an object having a `foo` key, and return its value. In the type annotation you may notice `a` and `b`, they’re basically placeholders for stuff Elm doesn’t know about, so you can pretty much read it like that:

```elm
> .foo
<function> : { ¯\_(ツ)_/¯ | foo : ¯\_(ツ)_/¯ } -> ¯\_(ツ)_/¯
```

Now since `.foo` is a function, we can pass our object as argument, and get the correct value:

```elm
> .foo myObject
"bar" : String
```

This may not seem very fascinating but it is *crazy useful* for composition, as we’ll see later.

One of the major differences between Elm and Javascript is that we cannot access fields that do not exist:

```elm
> myObject.nope
-- TYPE MISMATCH

`myObject` does not have a field named `nope`.

6|   myObject.nope
     ^^^^^^^^^^^^^
The type of `myObject` is:

    { baz : number, foo : String }

Which does not contain a field named `nope`.

Hint: The record fields do not match up. One has baz and foo. The other has
nope.
```

That means no `null`, no `undefined`, etc. Again, Elm is about *predictability*, and `null` is one of the major pitfalls of modern applications. The language goes very deep into avoiding anything unexpected **ever happens** and this is part of it.

## I want to get off Mr. REPL’s wild ride

Ok we’ve played enough in the REPL, this isn’t what we’re here for, let’s CODE SOME STUFF. Let’s start by creating a `Main.elm` file, within a `src/` folder. Note that the name of that file has no particular significance, `Main.elm` is just kind of a “convention” amongst Elm developers, but we could have named if `Foobar.elm` with the same results.

Before writing anything, let’s make the file empty for now, and boot it up. The Elm platform comes with a development server called `elm reactor` so let’s type that and navigate to the URL it’ll give you, which should show something like this:

Click on the `src` folder then on `Main.elm`. If you do so, Elm will tell you that it expected literally anything from you and that you gave it an empty file so it’s shaking its head in disappointment:

```elm
-- SYNTAX PROBLEM
Main.elm

I ran into something unexpected when parsing your code!

I am looking for one of the following things:

    "{-|"
    a definition or type annotation
    a module declaration
    a port declaration
    a type declaration
    an import
    an infix declaration
    whitespace
```

> “Even whitespace dude… just… just type some spaces, seriously, anything”

### Setting up our web application

As I mentioned in the introduction, Elm is not a *generic* language, it is a language to build web applications. Which means that the framework is built into the language. And in this case, to run the application, Elm is expecting us to have a `main` function that will return some HTML. In a way `main` is the entry point – if you’re familiar with C it’s the same idea – so let’s add it to our file:

**src/Main.elm**

```elm
main = "Hello world"
```

Refresh the page (the reactor will recompile by itself in the background), and you’ll see… another error. This time, Elm is saying that it wanted you to give it HTML or SVG or something, but you gave it a string which is not a webapp so he’s starting to be really pissed off.

Indeed, Elm does not consider strings to be Html elements in and of themselves. Instead we need to give Elm an HTML `Text` node, which you can find in the `Html` module.

To import a package in Elm, the syntax is a bit different to what you’re used to but not that far off, we’re going to call `import Html`, and from that module we’re going to use the `text` function which renders an HTML text node:

```elm
import Html

main = Html.text "Hello world"
```

Now in Elm when you import a package, by default it imports it as itself, which is why we call `Html.text`. It is the equivalent of the following code in Javascript:

```elm
import Html from "html";

const main = Html.text("Hello word");
```

But we can also import only the relevant parts, and expose them in the current scope. For this, we use the `import X exposing Y` syntax. In this case, we want to import `Html` and expose `text`. Once a function is *exposed*, it means that it is available in the current scope as itself:

```elm
import Html exposing (text)

main = text "Hello world"
```

Again translated to Javascript:

```javascript
import Html, { text } from "html";

const main = text("Hello word");
```

If you refresh the page, your application should now actually be returning HTML and you should see the gloriousness of your Web 5.0 page.

### Writing some actual HTML

Ok, we now know how to write some text to a page, but what about HTML?

In Elm, since everything is a function, you also write your HTML with functions. The same way you do in Javascript with packages like [hyperscript](https://github.com/dominictarr/hyperscript) or the same way React does underneath the JSX syntax.

Every element is a function that takes two arguments: its attributes, and its children. Let’s wrap our text in a div per example:

**src/Main.elm**

```elm
import Html exposing (text)

main = div [] [text "Hello world"]
```

Here as I explained, we are calling the `div` function with two arguments: its attributes (which there are none, so we just pass an empty list `[]`) and its children (our text, also within a list). If you’re confused with this bit, remember that they’re just arrays, we could per example have this:

main = div \[\] \[text "Hello world", text "Some other text"\]

If you try to refresh your page, Elm will complain that it doesn’t know where `div` comes from:

```elm
Cannot find variable `div`

3| main = div [] [text "Hello world"]
          ^^^
Maybe you want one of the following?

    min
    pi
    sin
    Html.div
```

It does however try to guess what we meant, in this case we indeed meant `Html.div`. Now we could rewrite our example as `main = Html.div bla bla`, **or** we could also update our import to show `exposing (text, div)`. **But**, there are like a hundred elements in HTML and nobody got time to remember them all so let’s import *all the elements*:

**src/Main.elm**

```elm
import Html exposing (..)

main = div [] [text "Hello world"]
```

The `(..)` syntax is used to signify “expose all”, Javascript doesn’t really have an equivalent but it isn’t that far from doing that:

```javascript
import {text, div, html, body, etc and so forth for all elements} from 'html';
```

This may look dangerous but in Elm everything is a module, there is no global context, so while you’re exposing a lot of functions into the scope, you’re only doing so *in that file*. If you go into another file and try to call `text` as is, it won’t work.

If you refresh your page, you should see “Hello world” again, which is good, but let’s try to add a class to it. As said before, the first argument to any HTML function is a list of attributes, but what is an attribute? If you answered “Also a function” then you are correct, cause this is Elm and everything is a function, even me, even you, we all functions now. So to apply a class to an element, we call the `class` function, imported from `Html.Attributes`:

```elm
import Html exposing (..)
import Html.Attributes exposing (class)

main = div [class "container"] [text "Hello world"]
```

If you refresh your page, well, you won’t see the difference but if you look in your inspector of choice we do see that our class was properly applied:

## Compiling our application

What we typed before is some HTML, but we’re not gonna code our HTML context like that (I’m talking about the head, body, doctype, etc). Instead we’re going to *embed* that HTML onto an existing element. If you’re familiar with React this is the exact same mechanism that when calling `ReactDOM.render`: everything we do and render will be rendered *within* an existing HTML element on an existing page.

Let’s create a basic `index.html` and place it into a `public` folder:

**public/index.html**

```jsx
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <main></main>
    <script src="main.js"></script>
</body>
</html>
```

The endgame here is to embed our application onto that `main` element. So first, we’ll need to compile our Elm code to a `main.js` file since that’s what we included here. To do so, we’re going to use another tool from the elm platform: `elm make`:

```
$ elm make src/Main.elm
Success! Compiled 1 module.
Successfully generated index.html
```

If you run this, you’ll notice that his is not quite what we want: Elm generated an `index.html` of his own with all the Javascript thrown in like a madman. We want a `main.js` instead so we need to specify the format:

```
$ elm make src/Main.elm --output public/main.js
Success! Compiled 1 module.
Successfully generated public/main.js
```

There, now we have our javascript file compiled. Remember how I said we needed to embed our application onto an element? If you open the `public/index.html` file in your browser, as it is, you actually already have access to what we need:

As you can see, Elm defined a global `Elm` object onto the `window`. Inside it is our `Main` module (since our file is called `Main.elm`), and that module has two methods:

- `embed` is what we want, and accepts the arguments we’d expect it to
- `fullscreen` is basically just an alias for `embed(document.body)` (sort of)

You can see a mention of `flags` here but we’ll see that later. Ok so let’s write the code we need in our HTML file:

**index.html**

```jsx
<script src="main.js"></script>
<script>
    Elm.Main.embed(document.querySelector('main'));
</script>
```

Refresh and miracle, here is our Hello World. Do note that `elm make` has no `--watch` flag, it is meant for basic compilation. We’ll setup an actual build tool later on but for now let’s just define a simple NPM script to do that for us. Open up your `package.json` file and add a `build` script to do what we just did:

**package.json**

```json
{
    "name": "elm-blogpost",
    "scripts": {
        "build": "elm make src/Main.elm --output public/main.js"
    },
    "dependencies": {
        "elm": "^0.18.0"
    }
}
```

Try to run `npm run build` and if everything went well it’ll say “Compiled 1 module” which is good. On that note, I think that’s enough tinkering, let’s go back to coding some Elm!

---

## The Elm architecture

Now we have an actual page, and an actual Elm file to work with, let’s jump right into it. For our first baby steps, we’re going to do something **hella basic**, we’re going to create a counter, with a + and – button. I know you want to go off right now and code your fantastic “Uber for Pretzels” app idea but you looked at me weird when I said `+` was a function so trust me.

Every web application (not *website*) can be described in the following way:

- It has a state, holding information about itself
- It has actions, which describe stuff your application can do
- It has a way to accept these actions and return a new state
- It has a way to display said state

If you’re familiar with Redux then this should start sounding familiar right about now, because that is exactly what React/Redux is: the store is your state, reducers receive actions and return a new state, and React renders that state into HTML. Well guess what, it’s exactly the same in Elm: every Elm application is divided into these four parts:

- **Model** is your state, it’s a representation of the data your webapp can hold
- **Messages** are your actions, which are then sent to…
- **Update** is your reducer, it’s a function that receives a message and the state and returns a new state
- **View** is your… view? It receives the model and returns HTML/SVG

### The model

Let’s start by the Model because that is the easiest part. We’re going to define a new type, called `Model`, which we’ll use to tell Elm everywhere “This is what my data should look like”. There are two ways to create new types in Elm:

- By creating an actual type using the `type MyType = ???`
- By creating a type alias using `type alias MyType = ???`

We’ll go over the difference between the two and what each means in just a second.

In our case, the smallest possible representation our state could have, would be simply and `Int`, so we would say `type alias Model = Int`, because it’s just a counter, ain’t nothing else that we need to know. *However* the fact is that 99.84% of applications never have just “one” thing they need to be aware of so it is recommended to instead make your model an object:

**src/Main.elm**

```elm
import Html exposing (..)
import Html.Attributes exposing (class)

type alias Model = {counter : Int}

main = div [class "container"] [text "Hello world"]
```

That’s it, our state is a record, that has a `counter` property, which is an int. Note that we used `:` here, because this is a *type annotation*. We’re not declaring a variable, this isn’t an actual object it’s an **alias** for an object that has a specific shape that we want, kind of like that rock you found on the beach once and named Peter. If we create a new record `{counter = 2}`, even if we don’t explicitly say that it’s an instance of Model, it still is because it quacks like a Model.

That’s the difference between a type and a type alias: a type alias is just a nickname we gave to another bunch of types, it’s virtual, it does not actually exist, if you pass something that sorta looks like it, it’s fine.

Whereas if you declare an actual type, then it’s real. It exists, if a function asks for `MyCustomType`, then it better be an instance of one.

Underneath `type alias Model = ...` we’ll also define our *initial model*: the default values the app will have when it starts. In our case, it’s just going to be setting the counter at 0:

```elm
type alias Model = {counter : Int}

model = {counter = 0}
```

### The message

The message is a type (not a type alias) that represents anything that can happen to our application. In our case what can happen to our counter? It can increment or decrement, so let’s define that. We’ll use `type Message = ???` and then we’ll enumerate *what kind of messages* our app will receive, separated by a `|`:

**src/Main.elm**

```elm
import Html exposing (..)
import Html.Attributes exposing (class)

type alias Model = {counter : Int}

model = {counter = 0}

type Message = Increment | Decrement

main = div [class "container"] [text "Hello world"]
```

If you’re like me when I started learning Elm, your first reaction might be “Where the hell do Increment and Decrement come from?”. Nowhere, we just *defined them*: this is called a type union (or [tagged union](https://www.wikiwand.com/en/Tagged%5Funion)). Think of your message as an enumartion of arbitrary types, let’s boot up ye old Elm REPL to see what I mean:

```elm
> type Message = Increment | Decrement

> someMessage = Increment
Increment : Repl.Message

> someOtherMessage = Decrement
Decrement : Repl.Message

> Message
Cannot find variable `Message`
```

As you can see, if we create a variable `myMessage` and assign it the value `Increment`, then Elm knows that `myMessage` is of the `Message` type. But we cannot create directly a Message because it can mean multiple things.

Think of it like this: 5 and 10 are both `Int`s, but you cannot create an `Int` without knowing the value, you can’t do like `someNumber = Int` you have to say *what* number and do `someNumber = 5`.

This is the same mechanism here, both `Increment` and `Decrement` are examples of Messages, but you cannot just straight up create a Message without saying what *kind* of message.

### The update

As I mentioned before, reducers in Redux were inspired by updaters in Elm, most of the time a reducer in Redux looks like that: it receives the current data of the application (model) and what to do with it (message). It then decides *how* to update the data depending on the *type* of the message.

It can be done any number of way (with `if`s and `else`s) but usually it is done through a `switch`:

```javascript
function reducer(model, message) {
    switch (message.type) {
        case "INCREMENT":
            return model + 1;

        case "DECREMENT":
            return model - 1;

        default:
            return model;
    }
}
```

Then you would call that function on the state, with a particular message:

```javascript
reducer({ counter: 0 }, { type: "INCREMENT" }); // {counter: 1}
```

Well that’s exactly what an updater is in Elm. No seriously, I mean this is *exactly* what an updater is, with the switch and all. Let’s start by declaring our function, like in redux it accepts our model and a message, and since we don’t know what to return *yet*, let’s just make it return the model as is for now.

```elm
update message model = model
```

Before we proceed, let’s talk about type annotations. Elm is *very smart* at figuring out the types of stuff, so chances are if you used this update function in the wild with enough context it’ll figure out that `model` is a `Model` and `message` is a `Message`. That being said, Elm can only cover your ass so much so it’s best practices to always define your types. We’ve seen the syntax used to do this before (`variable : argument -> other argument -> ... -> whatever is returned`) but where do we put that? Simply enough, right above:

```elm
update : Message -> Model -> Model
update message model = model
```

Little recap if you’re lost: we basically said “update is a function that accepts a message, then it accepts a model, and when it’s done accepting things, it’ll return a model”.

Now this is nice and everything, but we’re not doing anything of our `message` variable so let’s write a switch. The syntax for a switch in Elm is (again) *relatively similar* to Javascript but also kind of not the same:

```elm
case someVariable of
  String -> "what to return if someVariable is a string"
  Int -> "what to return if someVariable is an int"
  _ -> "what to return by default otherwise"
```

As you can see, I’m abusing the word “switch” a bit here as we’re not switching on the **value** (like in JS) but on the **type**. Also as a reminder, returns are implicit. With that information in mind, we want to write a switch on `message`, and increment `model.counter` if it’s `Increment`, and decrement it if it’s `Decrement`. Let’s start by `Increment`:

```elm
update : Message -> Model -> Model
update message model =
  case message of
    Increment -> ??? return a new model here ???
```

Ok, what do we put here? Our counter `int` is on a property of the Model record, that means that we cannot just do `Increment -> model.counter + 1` because that would just return something like “2” and we want to return a new Model.

So we have to update the *property itself* on the record and then return said record. To accomplish that in Javascript, without breaking immutability, you would do the following:

```elm
switch ((action.type, model)) {
    case "INCREMENT":
        return { ...model, counter: model.counter + 1 };
}
```

As usual, syntax slightly differs in Elm but should be familiar enough for you to not get lost too much:

```elm
update : Message -> Model -> Model
update message model =
  case message of
    Increment -> {model | counter = model.counter + 1}
```

The idea is the same: we create a *new object*, then we “copy” our previous object’s properties on it through `|` so that everything that was in the old model is copied onto the new one, and then we update the property on our new model.

Do note that `counter` is the only property we have on `Model` so far, so this syntax has currently no benefits over doing this:

```elm
update message model =
  case message of
    Increment -> {counter = model.counter + 1}
```

This is just so you get used to the idea of creating new records from other records because it is very handy.

Let’s stop there briefly, and try to compile. Run `npm run build` in your console, and you’ll get the following message:

```elm
This `case` does not have branches for all possibilities.

 9|>    case message of
10|>        Increment -> {model | counter = model.counter + 1}

You need to account for the following values:

    Decrement

Add a branch to cover this pattern!
```

Elm saw that our application could do two things: increment and decrement. But we only told it what happened when we increment, so it refuses to compile because *not all possibilities are accounted for*. This is something you’ll encounter a lot in Elm, as I mentioned before it will try to shield you from unexpected and will refuse to compile if you do not account for possible errors. So let’s write our `Decrement` branch. If you’re with me so far, it’s pretty straightforward, we just have to write the same thing with a `-` instead of a `+`:

```elm
update : Message -> Model -> Model
update message model =
  case message of
    Increment -> {model | counter = model.counter + 1}
    Decrement -> {model | counter = model.counter - 1}
```

And there we go, we now have an `update` function that takes into account every possible thing that could be happening in our application.

You might say “Where is the default branch? All good switches have a default branch right?” and you’re correct but not in Elm. Because we know that Message can only ever be one of those two types, we don’t need to add a default branch because we’re absolutely certain that that will *never* happen. Because if there was any possibility for Message to be something else, the app would not have compiled. It’s as simple as that.

### The view

We saw briefly how to conjure up some HTML before, so this is going to go a bit faster. What we want is:

- Two buttons, a + and a –
- The current count

#### Laying the foundations

Let’s define a `view` variable and lay the HTML foundations of that:

```elm
view =
    div [] [
        button [] [text "-"],
        text "5",
        button [] [text "+"]
    ]
```

Remember that the first argument to all HTML functions is a list of attributes (excepted `text` because a text node has no attributes). The second is a list of children, so we created a `div` with three children: `button, text, button`.

Something important to note: Elm, just like React and other libraries, will not let a variable or a function return a bunch of elements without a parent node. You only ever return *one element*, which can then have as many children as you’d like. This is why we wrapped everything in a `div`.

Let’s check in the browser see if we’re ok. Now if you remember, the entry point of our app is the `main` variable so for now let’s just say `main = view`:

**src/Main.elm**

```elm
import Html exposing (..)
import Html.Attributes exposing (class)

type alias Model = {counter : Int}

model : Model
model = {counter = 0}

type Message = Increment | Decrement

update : Message -> Model -> Model
update message model =
    case message of
        Increment -> {model | counter = model.counter + 1}
        Decrement -> {model | counter = model.counter - 1}

view =
    div [] [
        button [] [text "-"],
        text "5",
        button [] [text "+"]
    ]

main = view
```

Run `npm run build`, then open our `public/index.html` file in your browser and there we go, wonderfully disgusting:

#### Using our data

For the actual text, we currently hardcoded “5” but let’s use the data from our model. In order to do so, we’re going to make `view` a function that accepts a `Model` and returns some `Html`. This will allow us to use `model.counter` to display the proper count. If you remember, to define arguments we write `view model = ...`:

```elm
view model =
    div [] [
        button [] [text "-"],
        text model.counter,
        button [] [text "+"]
    ]
```

We can then call our `view` as a function with the `model` variable we defined earlier to display it:

```elm
main = view model
```

If you try to run `npm run build` at this stage, you’ll get an interesting error:

```elm
-- TYPE MISMATCH
The argument to function `view` is causing a mismatch.

28|        view model
                ^^^^^
Function `view` is expecting the argument to be:

    { counter : String }

But it is:

    Model
```

Why? Because `Html.text` expects `model.counter` to be a string, but we passed `3` which is a number.

In order to fix this, we’ll use a core function of Elm called `toString` which converts stuff to strings (I know, you’re flabbergasted). So let’s call it on our `model.counter` variable in the `view` function:

```elm
view model =
    div [] [
        button [] [text "-"],
        text (toString model.counter),
        button [] [text "+"]
    ]
```

Notice that we wrapped it within parenthesis to avoid the `Html.text` function thinking that we passed it two arguments (as if we had done `text(toString, model.counter)` instead of `text(toString(model.counter))`).

#### Adding interactions

Now let’s make our buttons actually do something. For this we we’ll use another module from the `Html` package: `Html.Events`. Let’s import it and expose the `onClick` function:

```
import Html.Events exposing (onClick)
```

Here `onClick` is an attribute function (just like `class`), ie. it returns an instance of `Html.Attribute`. But what do we pass to it?

Remember when we defined our Message? We said “A message is either `Increment` or `Decrement`” – well that’s exactly what we need here. We’re passing the type itself as argument to onClick:

```elm
view model =
    div [] [
        button [onClick Decrement] [text "-"],
        text (toString model.counter),
        button [onClick Increment] [text "+"]
    ]
```

While we’re at it, let’s add a type annotation to our `view` function. We know it accepts a `Model` and returns some `Html` so let’s naively try that:

```elm
view : Model -> Html
view model = ...
```

If you try to build the app, here is what Elm tells you:

```elm
-- TOO FEW ARGUMENTS
Type Html.Html has too few arguments.

18| view : Model -> Html
                    ^^^^
Expecting 1, but got 0.
```

This one is **very** tricky to grasp at first, so let me walk you through what the problem is. We told Elm that our app returned Html, but if you *goto* the definition of HTML in your editor/IDE of choice, here is what you will see:

```elm
type alias Html msg = VirtualDom.Node msg
```

We read that it’s expecting to know what kind of *message* will this particular piece of HTML propagate. We know this! It’s going to be a `Message`, so let’s pass that as argument to `Html`:

```elm
view : Model -> Html Message
view model = ...
```

This is where you might start to get lost but this is just generics. If you’re familiar with them, this would be the equivalent Typescript annotation:

```javascript
const view: Model => Html<Message> =
    function(model) { ... }
```

I’m not gonna lie I don’t know the specifics of why this is necessary (internal optimization I’m assuming) but when defining the type of a function returning HTML, you need to specify what kind of message it can possibly send. Usually you only have one `Message` per app so most of your annotations will look the same (you can usually omit them for most HTML functions unless they have specific arguments and such).

Now that this is taken care of, if you look at this piece of code from afar, you may notice that we’re repeating ourselves here (I know it’s like three lines but imagine this is a real app). How do we organize our logic into reusable pieces? MOAR functions, that’s goddamn right, hide the look of surprise on your face.

Let’s define a `counterButton` function. Think about what we need to pass to it: we need to tell it what message it’ll send, and what its text will be, so something like `counterButton message label = ...`. Easily enough, we can do just that to split our view into reusable parts:

```elm
view : Model -> Html Message
view model =
    div [] [
        counterButton Decrement "-",
        text (toString model.counter),
        counterButton Increment "+"
    ]

counterButton : Message -> String -> Html Message
counterButton message label =
    button [onClick message] [text label]
```

Always remember: “It’s just functions”. There’s no black magic, no special syntax to follow for this to work, it’s all just functions calling other functions, all in the family, Lannister style. This is one of benefits of Elm (and functional languages in general): while the initial syntax barrier requires some work to overcome. Once you’re through, there is no difficulty curve, it’s smooth sailing.

Also note that the order of functions does not matter. We defined `counterButton` after the function using it, since it’s all compiled, there’s no worry to have about that. We could put our `main` all at the top before anything’s defined and it would still work.

### Joining all the parts together

Great, so we have a model, an updater/message, and a view. How do we make it all work together though? You’ll notice if you try to build our current application and click on a button, nothing happens.

To bind the pieces of our app, we need to return a `Program`. A program is a special type defined internally in Elm that describes how an application *behaves*.

You could create a Program yourself but Elm also comes with some examples of programs directly into the `Html` package, which means that by doing `import Html exposing (..)` we actually already brought some program functions into scope. There are three of them:

- `Html.beginnerProgram` is oriented at newcomers and ask of you a model, view and update (this is what we’re going to use)
- `Html.program` asks the same, but also allows you to use subscriptions and commands (which are used to manage events and side effects)
- `Html.programWithFlags` is the same thing as above but with the additional benefit that you can pass it some data from Javascript to initialize it. You could per example already have some data in JS that you would pass Elm to create your initial model, or some environment variable that you’d like Elm to know about, or to dispatch some events, stuff like that.

We’ll use the first one for now. There’s only one issue, what do we pass to it? Well if you ever ask yourself that, remember that you can always check out what kind of arguments we need to pass to something, directly in `elm repl`:

```elm
> import Html
> Html.beginnerProgram
<function>
    : { model : model
      , update : msg -> model -> model
      , view : model -> Html.Html msg
      }
      -> Platform.Program Basics.Never model msg
```

Ok so `Html.beginnerProgram` is a `<function>`, it accepts a record with three keys: a model, an update, and a view, and then it returns a `Program`.

If you think about it, we actually already have all we need ready to be used: we have a `model` variable, an `update` function and a `view` function, we just need to create a record from these three variables, so let’s do just that. We’re basically going to just assign each variable to its corresponding key on a record:

```elm
main = beginnerProgram {model = model, update = update, view = view}
```

This is just a basic record, if we had named our view variable `makeMyView` then it’d be `beginnerProgram {view = makeMyView, ...}` etc. You don’t *have to* name your variables `update`, `model` and such, it’s just good practices.

Run build again and refresh your browser and there we go:

> Uber for Pretzels, here we come

Before we move on to the next part, let’s cleanup our file a bit. You know what it needs? Comments, everything is always better with more comments. And how do you comment in Elm? With `-- foobar` for single line comments, and `{- foobar -}` for multiline, example:

```elm
-- This code adds 1 and 1
addStuff = 1 + 1

{-
  This code adds 1
  and 1
  wow
  much numbers
-}
addStuff = 1 + 1
```

So let’s separate a bit the pieces of our file with some comments to clearly delimitate the various sections of it:

```elm
import Html exposing (..)
import Html.Attributes exposing (class)
import Html.Events exposing (onClick)

-- Model

type alias Model = {counter : Int}

model : Model
model = {counter = 0}

-- Update

type Message = Increment | Decrement

update : Message -> Model -> Model
update message model =
    case message of
        Increment -> {model | counter = model.counter + 1}
        Decrement -> {model | counter = model.counter - 1}

-- View

view : Model -> Html Message
view model =
    div [] [
        counterButton Decrement "-",
        text (toString model.counter),
        counterButton Increment "+"
    ]

counterButton : Message -> String -> Html Message
counterButton message label =
    button [onClick message] [text label]

-- Main

main = beginnerProgram {model = model, update = update, view = view}
```

It’s not much but it doesn’t hurt and it’ll help us see a bit more clearly so, yay.

## Setting up a build system

Before we move on, let’s setup an actual build system so we don’t have to keep running `npm run build` all the time. There are various bindings for Elm (Gulp, Grunt, etc) but since I love me some chunks let’s use Webpack. If you’re not familiar with it, [we have a great article about it](https://madewithlove.com/blog/webpack-your-bags/) written surely by someone very smart I guess whoever he is.

Before we begin, here’s what you should have in terms of files and folders:

```
├── elm-stuff
├── node_modules
├── public
│   └── index.html
├── src
│   └── Main.elm
├── package.json
└── elm-package.json

```

### Setting up a basic Webpack build

We’ll need two things at first, Webpack and the Elm loader:

```
$ npm install webpack elm-webpack-loader --save-dev
```

Let’s split the Javascript that we hardcoded in `public/index.html` into its own file named `index.js`, and place it inside `src/` as well. We’ll need to get the `Elm` variable from somewhere, and the Elm loader is going to give us just that when importing an Elm file so let’s add an import for our Elm file at the top:

**src/index.js**

```javascript
const Elm = require("./Main.elm");

Elm.Main.embed(document.querySelector("body"));
```

Now let’s create our Webpack configuration, it’s going to be very basic:

**webpack.config.js**

```json
module.exports = {
    entry: "./src/index.js",
    output: {
        filename: "main.js",
        path: __dirname + "/public",
    },
    module: {
        rules: [{ test: /\.elm/, use: "elm-webpack-loader" }],
    },
};
```

Here’s what it says if you’re not familiar:

- The file we want to compile is `./src/index.js`
- We want to compile it to `public/main.js`
- We want to load all `.elm` files we find with the `elm-webpack-loader` package.

Next we’ll setup a plugin to automatically create our `public/index.html` file with the correct `script` tag to the built assets. For this we’ll need a plugin:

```
npm install html-webpack-plugin --save-dev
```

There’s no need to configure anything besides the page title which we’ll pass through an options object:

```javascript
const HtmlPlugin = require("html-webpack-plugin");

module.exports = {
    // [...]
    plugins: [new HtmlPlugin({ title: "MY COOL ELM APP" })],
};
```

Let’s give it a shot, run `webpack` and if it all worked here is what you will get:

```
$ webpack
Hash: 2fbe3770b313e328dae9
Version: webpack 3.10.0
Time: 1188ms
     Asset       Size  Chunks             Chunk Names
   main.js     201 kB       0  [emitted]  main
index.html  184 bytes          [emitted]
   [0] ./src/index.js 84 bytes {0} [built]
   [1] ./src/Main.elm 198 kB {0} [built]
Child html-webpack-plugin for "index.html":
     1 asset
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
        + 2 hidden modules
```

The plugin will have generated a new `public/index.html` file with the correct script tag so that’s one less thing to worry about, which is always nice.

### Setting up hot reloading

One of the advantages of Webpack is that it supports hot reloading (ie. “patching” the current page with new code without having to reload it). Setting up is fairly straightforward, we’ll use Webpack’s dev server and the relevant Elm plugin:

```
npm install webpack-dev-server elm-hot-loader --dev
```

To set it up, we just need to slightly amend the loader in our Webpack configuration:

```json
{test: /\.elm/, use: ['elm-hot-loader', 'elm-webpack-loader']},
```

This is the final file:

```javascript
const HtmlPlugin = require("html-webpack-plugin");

module.exports = {
    entry: "./src/index.js",
    output: {
        filename: "main.js",
        path: __dirname + "/public",
    },
    module: {
        rules: [
            { test: /\.elm/, use: ["elm-hot-loader", "elm-webpack-loader"] },
        ],
    },
    plugins: [new HtmlPlugin({ title: "MY COOL ELM APP" })],
};
```

Now, let’s add a script to our `package.json` to boot up a development server, and while we’re at it let’s also update our old `build` script to simply call `webpack`:

**package.json**

```json
{
    "name": "elm-blogpost",
    "scripts": {
        "build": "webpack",
        "start": "webpack-dev-server --inline --hot"
    },
    "dependencies": {
        "elm": "^0.18.0"
    },
    "devDependencies": {
        "elm-hot-loader": "^0.4.2",
        "elm-webpack-loader": "^3.0.6",
        "html-webpack-plugin": "^2.24.1",
        "webpack": "^1.13.3",
        "webpack-dev-server": "^1.16.2"
    }
}
```

Let’s see if it all works, run `npm start` in your terminal and navigate to http://localhost:8080/ – you should see the application as we left it before. Now go into `src/Main.elm` and try to change per example the label of one of the buttons.

If you look back in the browser, you’ll see that the page has been updated without any intervention from your part, and more importantly the state was left intact (ie it did not reset the counter). The page wasn’t refreshed, instead its code was *updated live*.

---

## Advanced messaging and user input

### Messages with arguments

Up until now our messages have been very basic. We communicated with our app one word at a time, “increment” or “decrement” or “groot” but this is rarely going to be the case in actual applications. More often that not, you’ll say something like “Hey app, please do X with Y”.

So how do we create messages that have arguments? Let’s try to add an `IncrementBy` message to our app, allowing us to increment the counter by any number.

The first step is to update our `Message` type to add the new possibility. We’re going to append `IncrementBy` to it but we want it to have an argument which would be an `Int`, so… that’s exactly what we’re going to write:

```elm
type Message = Increment | Decrement | IncrementBy Int
```

We would then create this message by doing per example `incrementByFive = IncrementBy 5` just like calling a function.

If you still have Webpack running from the previous section, you should see an error popping up in the console telling you to add this new possibility to our `update` function.

When a message has arguments, they’ll be received on the left-hand side of the switch condition, that means that where we had `Increment -> ...` we’d have `IncrementBy howMany -> ...`. With this in mind, it’s fairly easy to copy/paste the line above and adapt it to our needs:

```elm
update : Message -> Model -> Model
update message model =
    case message of
        Increment -> {model | counter = model.counter + 1}
        Decrement -> {model | counter = model.counter - 1}
        IncrementBy howMany -> {model | counter = model.counter + howMany}
```

Again, remember that this is all just functions. If we wanted to abstract away that feature under one, we could totally do that, per example:

```elm
incrementCounterBy : Model -> Int -> Model
incrementCounterBy model howMany = {model | counter = model.counter + howMany}

update : Message -> Model -> Model
update message model =
    case message of
        Increment -> incrementCounterBy model 1
        Decrement -> incrementCounterBy model -1
        IncrementBy howMany -> incrementCounterBy model howMany
```

Let’s keep it simple for now though and keep the repetition so we don’t spread out too much. Remember that we’re not building an actual application yet here, this is just for learning, in a real app there are dozens of simpler ways to do what we’re doing.

Anyway, we now have an `IncrementBy` message which our update knows about. The compiler should run fine but we still need to add a way to dispatch said message.

For this we need to update our view with a new thing: a text input so the user can enter how much to increment by, and a button to do just that.

For the button, we don’t need to define anything else because we already defined a `counterButton` function which we can reuse. You pass arguments to messages the same as for functions, example:

```elm
button [onClick (IncrementBy 5)] [text "Increment by 5"]

-- Or in our case
counterButton (IncrementBy 5) "Increment by 5"
```

Again, the parentheses are there to avoid `onClick` thinking this is an argument, ie. we want `onClick(IncrementBy(5))` and not `onClick(IncrementBy, 5)`.

For the input, we will need somewhere to keep track of the current value held by the input, instead of getting it when dispatching the message. If you’re familiar with React, this is called a **controlled input**:

- An uncontrolled input has whatever value it wants, and we grab that value at the precise moment where we want to do something with it, using DOM voodoo or extracting it from a Javascript `Event` object.
- A controlled input’s value is held somewhere else (state, redux, Model, can of tomato sauce, etc.) and the input always reflects that value, it is a *projection* of it. To use the value somewhere else, instead of grabbing it from the input, we instead directly use the value that we have stored aside and that the input itself used.

**Uncontrolled input**

```javascript
document
    .querySelector('input[name="foobar"]')
    .addEventListener("click", function(event) {
        // Do something with the value
        console.log(event.target.value);
    });
```

**Controlled input**

```javascript
const value = 5;

// On every "loop" of your app, make sure input
// holds the correct value
document.querySelector("input").value = value;

// Do something with the value somewhere else
console.log(value);
```

Basically in a environment with controlled inputs you have a single source of truth which your inputs reflect, whereas with uncontrolled inputs they *are* the source of truth.

Now why am I talking about this: uncontrolled inputs **are not a thing** in Elm. Why? Because they’re uncontrolled and if there’s one thing this language dislikes it’s things it has no control over, Javascript being one of them. Think of Elm as a country with very tightly-guarded and closed borders, while JS is the country right next door: we don’t trust *anything* coming from them cause JS is a big ball of randomness and quirks. Hence why the recommended design is to use controlled inputs.

All that to say: we need to update our `Model` to keep track of the input value. We know that it will be a string, so we just need to add that. You can name it however you want, we’ll name it `incrementBy` to be explicit:

```elm
type alias Model = {counter: Int, incrementBy: String}
```

Then we need to create a new message, to update that value. Again, naming is up to you, we’ll go with `SetIncrementBy String`:

```elm
type Message = Increment | Decrement | IncrementBy Int | SetIncrementBy String
```

Once this is done, the compiler will remind you to add this new possibility to your `update` function, using the same pattern as for `IncrementBy`:

```elm
update : Message -> Model -> Model
update message model =
    case message of
        Increment -> {model | counter = model.counter + 1}
        Decrement -> {model | counter = model.counter - 1}
        IncrementBy howMany -> {model | counter = model.counter + howMany}
        SetIncrementBy value -> {model | incrementBy = value}
```

It will also tell us that we need to update our `model` variable (which is our initial state) as currently Elm has no idea what to use as default for `incrementBy` so let’s just give him an empty string:

```elm
model = {counter = 5, incrementBy = ""}
```

Now all we have to do is create our input. We can use the `input` element from the `Html` package like we did for `div` and such. As for the event to dispatch our message on, we’ll use `onInput` which means “whenever the value of the input changes”. You’ll notice that I won’t be passing any argument to `SetIncrementBy` because `onInput` will already be passing the current value to whatever message we specify (just like `onChange` does in React):

```elm
input [type_ "number", onInput SetIncrementBy] []
```

Per example if we typed “foobar” then `SetIncrementBy` would be called with the argument `"foobar" : String`, simple enough.

You’ll also notice that I used `type_` and not `type`, because `type` is a reserved keyword (ie. if the language uses it so you can’t use it yourself). So the `Html` package instead exports the attribute as `type_`. This is a convention in Elm and will be the same for any reserved keyword. Since we aren’t exposing all attributes from `Html.Attributes`, we’ll need to add it to our import, same for `onInput`:

```elm
import Html.Attributes exposing (class, type_)
import Html.Events exposing (onClick, onInput)
```

The reason we don’t just change those to `exposing (..)` is that HTML has a *lot* of attributes and doing so would prevent us from being able to name our variables whatever we want since half the words in the english language are HTML attributes.

Now let’s put all this happy bunch together:

```elm
view model =
    div [] [
        counterButton Decrement "-",
        text (toString model.counter),
        counterButton Increment "+",
        counterButton (IncrementBy 5) "Increment By 5",
        input [type_ "number", onInput SetIncrementBy] []
    ]
```

Perfect! Or almost, you’ll notice that our custom increment is still hardcoded to `5` which isn’t good is it? Instead we want to use the value specified on the input. Luckily we know that it’s on our Model so we can access it, the same way we did to display the counter, by using `model.incrementBy`:

```elm
counterButton (IncrementBy model.incrementBy) "Increment By 5",
```

We’ll also need to update our text to show the actual value we’re passing. For this we’ll use the string concatenation operator that we saw in the introduction – `++` – to form the final string, like this:

```elm
counterButton (IncrementBy model.incrementBy) ("Increment By " ++ model.incrementBy),
```

Notice how we also wrapped the string in parenthesis, this isn’t mandatory in this case but it’s good practices to do so to improve code clarity. If the compiler is still running in your terminal (if not type `npm start` again) you’ll see that it’s telling us the following thing:

```elm
The argument to function `IncrementBy` is causing a mismatch.

32|                        IncrementBy model.incrementBy)
                                       ^^^^^^^^^^^^^^^^
Function `IncrementBy` is expecting the argument to be:

    Int

But it is:

    String
```

Well that makes sense doesn’t it? Our input value is a string, and `IncrementBy` wants a number. Fair enough. There are two ways to solve this:

1. Make `model.incrementBy` an `Int` by converting it as such on reception of `SetIncrementBy`
2. Convert `model.incrementBy` within our view

In this case, the second option is recommended: we don’t know if we’re gonna want to do something else with our input value later on maybe that would require it to be a string. We just know that we need it to be an int for this particular case, so it’d make sense to only convert it here.

But how do we convert a string to an int? You’re probably thinking “Well we just call `toInt` or something on it” and you’d be close but yet so far. You’ll see what I mean in a few seconds but first, let’s adapt our `view` variable to let us **prepare** our data accordingly before rendering the view.

### Data preparation

If you remember, earlier I said that everything in Elm *returns something*, and while this is generally true by default there is however a construct that you can use to prepare data before *acting* on it. This construct is called `let in`. Let’s see how to use it in a small abstract example, imagine that we have a function accepting two strings and we want to return them joined:

```elm
> joinStrings "foo" "bar"
"foobar" : String
```

We could write it in the following way:

```elm
joinStrings : String -> String -> String
joinStrings first second = first ++ second
```

But if (for some reason) we wanted to prepare our final string before returning it we could also write it like so:

```elm
joinStrings : String -> String -> String
joinStrings first second =
    let joined = first ++ second
    in
        joined
```

This may seem rather hard to parse at first, but you have to read it in a Javascript `let` kind of sense. In JS you would do something like this:

```javascript
function joinStrings(first, second) {
    let joined = first + second;

    return joined;
}
```

And just like in Javascript we can declare multiple things with a single let:

```elm
foobar : String -> String -> String
foobar foo bar =
    let
      baz = foo ++ "foo"
      qux = bar ++ "bar"
    in
      baz ++ qux

> foobar "foo" "bar"
"foofoobarbar" : String
```

Take your time to read this because this is a very important piece of Elm, you’ll need it in a lot of occasions. If you’re still having some trouble, let’s try to apply it to our little app here. We’d declare a `numberInput` variable where we’d convert `model.incrementBy` to an `Int`, using a function from the `String` module called `String.toInt`. Then we’d use it in our view, in the `in` section:

```elm
view : Model -> Html Message
view model =
    let
        numberInput = String.toInt model.incrementBy
    in
      div [] [
          counterButton Decrement "-",
          text (toString model.counter),
          counterButton Increment "+",
          counterButton (IncrementBy numberInput) ("Increment By " ++ model.incrementBy),
          input [type_ "number", onInput SetIncrementBy] []
      ]
```

Note that we still use `model.incrementBy` in the button’s label because in this case, we *do want* a string.

### Failures and results

Now try that and you’ll get a rather cryptic error message:

```elm
The argument to function `IncrementBy` is causing a mismatch.

34|                        IncrementBy numberInput)
                                       ^^^^^^^^^^^
Function `IncrementBy` is expecting the argument to be:

    Int

But it is:

    Result String Int
```

“What the hell is a Result?”, good question! You remember when you said “Well we just use toInt on the string and we’re good” and I laughed at you mockingly because I’m a dick? Think about it a bit.

- When we convert a number to a string, it is a straightforward operation. If we have `5` then it’ll become `"5"`, if we have `1.66` it’ll become `"1.66"`, it’s just wrapping the whole thing in quotes and good to go.
- But when you convert a string to a number, it isn’t as easy as that is it? Sure if your string is `"5"` then we have `5` but what if your string is `"foobar"` or `"1,97.6"` or `"three"`, what happens if `String.toInt` fails to convert our input to a number?

This is where `Result`s come into play. A `Result` is, surprisingly enough, the result of something – more precisely the result of something **than can fail**. If you remember, a while back I said Elm is all about predictability and taking into account edge-cases, and this is one of them (and a big one at that).

To force you to handle edge-cases, Elm introduced the `Result` type, let’s look at its definition:

```elm
{-| A `Result` is either `Ok` meaning the computation succeeded, or it is an
`Err` meaning that there was some failure.
-}
type Result error value
    = Ok value
    | Err error
```

If you take a look at the `Message` we defined it looks fairly similar, because it is also a *type union*, which means the same rules apply than for our messages: we can create a `Result` by either doing `Ok theResult` or `Err theError` but not `Result "error" 2`. Which makes sense, something can’t have both failed and succeeded, either the result is `Ok` (literally) or it’s an `Err` (usually a string with the actual error).

If you boot up the Elm REPL you can test this out very easily by trying to convert random strings to numbers:

```elm
> String.toInt "5"
Ok 5 : Result.Result String Int

> String.toInt "foobar"
Err "could not convert string 'foobar' to an Int" : Result.Result String Int
```

As you can see, each function that returns a `Result` also specifies the type of both possibilities. So when you see `Result String Int` what this means is “I’m going to return a result, either a `String` if it failed, or an `Int` if it worked, ok buddy?”.

This is fine and all but, even an `Ok` Result is still a Result, it’s still not an actual `Int`, how do we “unwrap” it to get our actual value? Well there are two ways. Just like for our `Message`, since `Result` is also a type union we can write a *switch* on it:

```elm
case (String.toInt model.incrementBy) of
  Ok number -> do something with the actual number
  Err error -> do something with the error
```

But for simple operations like converting a string to a number, more often than not, if there is an error a) you don’t care b) you can just use 0 as default. So that’s exactly what we’ll do!

The `Result` module also comes with a few helpers to deal with, well, results. One of those helpers is `Result.withDefault default result`, it accepts as first argument a default, and as second a `Result`. If the result failed it uses the default, if it worked it uses the actual value, yay! Let’s use it in our application by using `0` as default:

```elm
numberInput = Result.withDefault 0 (String.toInt model.incrementBy)
```

### Laying some pipe

Now, this **will** compile but there’s one pretty big issue with it, can you spot it? No? I’ll help: it’s horrendously unreadable because you need to read it *inside out*, ie. the first thing you read in the line (if you read left to right usually) is actually the *last* thing that you need to read in order to understand the code.

Luckily, as I mentioned in the introduction, Elm has a *lot* of function composition/application operators: operators that you can use to compose or apply functions (or chains of functions). Imagine how you would explain this line in actual English? Would you say:

> We have a default of 0 if what we’re going to do fails, cause we’re going to convert a string to an int, and that string is our input value

Or would you say:

> We have an input value, we convert it to string, and use 0 as default if it fails

Currently we have the first one, and while it’s correct, it’s a pretty dense way to explain the code. The second one makes more sense and flows more easily in your mind because it goes from input to output. Well good news, we can write our code *exactly* like that, using the `|>` operator.

The `|>` operator takes whatever is on its left, and passes it as the *last argument* to whatever is on its right. Dumbed-down example:

```elm
-- Before
String.toInt incrementBy

-- After
incrementBy |> String.toInt
```

This doesn’t look like much of an improvement, but it really starts to shine when you start having a whole chain of those just like in our case. So instead of our previous code, let’s rewrite it using `|>`:

```elm
-- Before
numberInput = Result.withDefault 0 (String.toInt model.incrementBy)

-- After
numberInput = model.incrementBy |> String.toInt |> Result.withDefault 0
```

That sure flows more easily right? If you’re having trouble grasping this code, a personal trick that I have is to mentally insert where the value would go:

```elm
numberInput = model.incrementBy |> String.toInt (value) |> Result.withDefault 0 (value)
```

And if you get a lot more of those and they start being too much for one line, you can just place each on a separate line:

```elm
numberInput =
  model.incrementBy
    |> String.toInt
    |> Result.withDefault 0
```

With that in mind, and since we don’t need nearly as many stuff on our page now that we can set a custom value, we can reduce our app to this:

**src/Main.elm**

```elm
import Html exposing (..)
import Html.Attributes exposing (class, type_)
import Html.Events exposing (onClick, onInput)

-- Model

type alias Model = {counter : Int, incrementBy : String}

model : Model
model = {counter = 0, incrementBy = ""}

-- Update

type Message = IncrementBy Int | SetIncrementBy String

update : Message -> Model -> Model
update message model =
    case message of
        IncrementBy howMuch -> {model | counter = model.counter + howMuch}
        SetIncrementBy value -> {model | incrementBy = value}

-- View

view : Model -> Html Message
view model =
    let
        numberInput = model.incrementBy
            |> String.toInt
            |> Result.withDefault 0
    in
      div [] [
          counterButton (IncrementBy numberInput) "Increment By",
          input [type_ "number", onInput SetIncrementBy] [],
          text (toString model.counter)
      ]

counterButton : Message -> String -> Html Message
counterButton message label =
    button [onClick message] [text label]

-- Main

main = beginnerProgram {model = model, update = update, view = view}
```

### Getting some closure

This is starting to look like an acceptable app for a throwaway dummy piece of code but we’re doing quite an unecessary step here: we’re storing the “increment by” as a string even though it will never be needed as such.

Wouldn’t it be nice if we could convert it to an int before sending it to our model? If we were in Javascript land, *one* way this could be accomplished would be to use a closure in our input’s event handler:

```jsx
// Before
<input type="number" onInput={setIncrementBy} />

// After
<input type="number" onInput={value => setIncrementBy(Number(value))} />
```

We can do the same in Elm through `\` and `->` which you can use in the same way you’d use the fat arrow `=>` in Javascript. This means that to rewrite our code in the same way as the JS example above, we would do the following:

```elm
-- Before
input [type_ "number", onInput SetIncrementBy] [],

-- After
input [
    type_ "number",
    onInput (\value -> value |> String.toInt |> Result.withDefault 0 |> SetIncrementBy)
] [],
```

The `\` denotes the start of an inline function – historically because `(\` looks like a lambda sign – and the `->` denotes its body. Both are needed in this case.

Note that you can of course prepare it the same way you’d do everything:

```elm
let
    handleOnInput = \value -> value
        |> String.toInt
        |> Result.withDefault 0
        |> SetIncrementBy
in
    -- [...]
        input [type_ "number", onInput handleOnInput] []
    -- [...]
```

The difference with doing it like this versus doing `handleOnInput value = value` being to your discretion, as both behave exactly the same (contrarily to Javascript).

---

## Conclusion

We’ve gone in quite different directions in this beginner introduction, and hopefully by now you have a clearer idea of how an Elm application works under the hood, and how you’d reason to build one. Over the course of this article of course we’ve stayed in the comforting warmth of the `beginnerProgram` but there are other, more powerful variations of this that include support for things such as routing, or subscriptions. We also haven’t delved into package management, testing, JS interoperability (ports), requests and all that. But the goal was more to give you an idea of how an Elm app is made, and what is done differently than in your standard Javascript app.

I’ve been very enthusiastic about this language so far but of course it wasn’t thought out to be applied to every use case you might have. It is very opiniated and intentionally restricts how you’d work in order to guide to one true accepted™ way it encourages.

### The Good Stuff

Elm is a statically typed language with a very precise and human friendly compiler. It’s a nice fit for SPAs and rapid iterations: because its type system is robust, you can refactor at east without fear of breaking anything. You can’t mess up an Elm codebase because it simply wouldn’t let you. Since it also comes with so many things built-in, it’s also quite fast to get started with since even without using packages you get the benefits of a Redux-like architecture and workflow.

Even to learn, Elm can be more approachable than other languages because while most of what it offers is of certain complexity, it doesn’t nearly have the baggage that languages like Javascript are dragging around. Everything was planned as a cohesive whole, as such it’s easier to reason with the language itself and to locate/use things because you know everything available was put for a reason.

### The Maybe Not As Good Stuff

That being said, Elm remains a small language, developped by one person with a clear vision. It doesn’t have Facebook-backing, nor weekly roadmaps or anything. A new stable version of the ecosystem comes out when it comes out and when the creator deems there are enough changes that warrant it. There can be extended periods of time between releases.

As a result the community is fairly small, and while you will find typings for a lot of popular libraries, you will still need to write them yourselves if there aren’t any, which can be complicated for a first time. The same can be said for resources in general: documentation, articles, etc.

Generally speaking the faults you’d want to input to Elm are at the implementation level. Design-wise, Elm does precisely what it was made for and with remarkable efficiency. But you will still hit regular road-blocks which learning it because of how alien some of its paradigms are when coming from Javascript. There will be obscure type errors, you will pull out some hair properly handling dates and anything unpure by design, or with your usual JS libraries.

There is also some things still missing in the language/framework as a whole, like server-side rendering and such which might be a definite block for some.

### The Subjective Median Opinion of the Stuff

I know these things because I’ve struggled with them personally, yet here I am because despite any of the flaws and growing pains that come with working with Elm, it remains a fantastic experience.

To have such a small little box that can do so much and with such safety is like having a Raspberry Pi for your applications. You’re probably not gonna do everything with it, but damn if it isn’t fun to tinker with it and create things rapidly, knowing there is nothing of value you can possibly mess up.

If this has you stuck between two chairs know that there are other languages out there that share Elm’s philosophy such as [Reason](https://reasonml.github.io/) and ReasonReact. So if you like the idea but not the implementation then I do recommend to check out these alteratives. There will be another article on Reason itself because I believe it’s a very valid choice when looking for Elm alternatives that have more backing at the moment.

---

### Would you like to know more?

If I’ve peaked your interest here are a couple of good resources to get properly started with:

- [Official website](http://elm-lang.org/) of course, since it contains some examples and a [book](https://guide.elm-lang.org/) to get started with
- [Elm Programming](http://elmprogramming.com/), another more approachable (and complete) online book with lots of very good information
- [Official subreddit](https://www.reddit.com/r/elm/), also a good active place to check out with lots of people ready to help and answers to lots of questions newcomers may have