Elm is a purely functional programming language, very similar to Haskell, that compiles into Javascript and simplifies the process of creating user interfaces. It includes some well thought out core libraries for working with data structures like Lists, Dicts, and Sets, and for managing Signals, which are fundamental to Elm’s Functional Reactive Programming approach to managing changes in state. The package manager and module system are pleasant to use, and it also provides a useful elm-reactor command that serves your project on localhost and automatically builds on any changes, making it incredibly quick and easy to get started.

You can run the following code snippets either from the online editor or by installing it, and then creating a directory with a Main.elm file in it and running elm-reactor.

Hello World!

Here’s the standard Hello World using only the core libraries, and demonstrating the module system, the type annotations, and the left pipe operator <| that is used for evaluating the Text.fromString "Hello World!"​ expression before passing it to the leftAligned function.

import Graphics.Element exposing (Element, leftAligned)
import Text

main : Element
main = leftAligned <| Text.fromString "Hello World!"

As you can see, everything is explicitly defined with none of the global variables that you encounter with Javascript. The main function is the point at which the app is evaluated altogether to display on the screen, and as such must return an Element type, refering to the HTML Element that will end up in the DOM.

Signal (Int, Int)

The following example (taken from http://elm-lang.org/examples) demonstrates the Signal concept that forms the basis of Elm’s Functional Reactive Programming approach:

import Graphics.Element exposing (Element, show)
import Mouse

main : Signal Element
main =
Signal.map show Mouse.position

In this case the main function returns a Signal Element, which can essentially be thought of as a list of Html Elements at each snapshot in time that an event has occured. The Mouse library is used to get the position of the cursor, which returns a type of Signal (Int, Int) where Signal can again be considered to be a list of the (Int, Int) tuple that represents the x and y coordinates of the mouse at various points in time, for instance:

[(0, 0)]                               -- Starting point at x = 0 and y = 0

[(0, 0), (10, 0)] -- Then moved to the right
[(0, 0), (10, 0), (10, 20)] -- Then moved down
[(0, 0), (10, 0), (10, 20), (5, 10)] -- Then moved to the left and up

This is then mapped to the show function that returns the value as an Element:

[<span>(0, 0)</span>]
[<span>(0, 0)</span>, <span>(10, 0)</span>]
[<span>(0, 0)</span>, <span>(10, 0)</span>, <span>(10, 20)</span>]
[<span>(0, 0)</span>, <span>(10, 0)</span>, <span>(10, 20)</span>, <span>(5, 10)</span>]

The outcome in the browser is the last item of the Signal list, representing the current state of the DOM body.

1 = 1

An important aspect of functional programming is to understand that the equals operator (=) is not used for assigning something to a variable, but actually signifies equality between the left and right sides just as it does in mathematical equations:

-- For example, in maths:
-- 5 = 2 + 3
-- .. so an addition function in Elm would be:
add x y = x + y
-- which evaluates to:
add 2 3 = 2 + 3

This means that the common idioms in imperative languages can’t be used, such as for (var = i; i < list.length; i += 1) {...}. Instead, lists of items are transformed by ‘mapping’ them to functions to return a new list with a different state, for example:

-- Define a list of ones
ones = [1, 1, 1]
twos = List.map (\one -> one * 2) ones

This example uses a simple lambda function to double each item in the list. These are often useful for small functions that you are unlikely to use again. Here’s how it would be written with a named function:

-- Define a list of ones
ones = [1, 1, 1]
double it = it * 2
twos = List.map double ones

Precedence

As with maths, you can specify what should be evaluated first with parentheses:

addAndHalve x y = (x + y) / 2

But Elm also provides two pipe operators (|> and <|) for different directions of evaluation:

-- Evaluates x + y first then halves the result
addAndHalve x y = x + y |> / 2

-- Evaluates x + y then passes the result to the halve function which returns
-- the final result
halve x = x / 2
addAndHalve x y = halve <| x + y

These might look strange, but it can be useful when describing a certain set of transformations in a particlular order:

blueDot =
circle 10
|> filled blue
|> move (20,20)
|> scale 2

This example evaluates a circle with radius 10 and applies it to the filled function to fill it with the colour blue, then takes this evaluation of this blue circle and applies it to the move function to move by (20, 20) and finally takes this evaluation of the blue circle that has been moved by (20, 20) and applies it to the scale function to multiply the scale by 2.