Getting Started With Elm

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.

importGraphics.Elementexposing(Element,leftAligned)importText

main:Elementmain=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:

importGraphics.Elementexposing(Element,show)importMouse

main:SignalElementmain=Signal.mapshowMouse.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:

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:addxy=x+y-- which evaluates to:add23=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 onesones=[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 onesones=[1,1,1]doubleit=it*2twos=List.mapdoubleones

Precedence

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

addAndHalvexy=(x+y)/2

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

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

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

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

blueDot=circle10|>filledblue|>move(20,20)|>scale2

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.