- Every element in a list must have the same type.
- Significant whitespace
- Uses structure equality rather than reference equality so that (3, 4) == (3, 4) is true. You can only compare values of the same type.
- If statements always have an else, and the branches must be the same type.
- Code is organized into modules
- Parenthesis are used for tuples and for precedence
- Has type inference, union types, and generics (type variables). Types are always uppercase. Read x : T as x has type T. Functions have types too.
- Has pattern matching in the case statement
- Has function argument destructuring
- Has auto currying (partially apply a function by passing only some of its arguments)
- Pragmatic and simple
- Convention over configuration
- Developer and beginner friendly with very good developer ergonomics. Compiler is very helpful.
- Great tooling
- Draws on strengths of functional programming, static type checking, and Haskell
- Draws of many of the best ideas in frameworks like React and reactive programming. Also borrows async ideas from Erlang.
["the", "quick", "brown", "fox"]
[1, 2, 3, 4, 5]Appending lists and strings (Appendable things can be combined with a ++ b)
"Hello " ++ "world!" -- "Hello world!"
[1..5] ++ [6..10] == [1..10] -- TrueList.head [1..5] -- Just 1
List.tail [1..5] -- Just [2, 3, 4, 5]
List.head [] -- NothingTuples: fixed length, heterogeneous:
("elm", 42)Records:
{ x = 3, y = 7 }
{ x = 3, y = 7 }.x -- 3
.y { x = 3, y = 7 } -- 7
person = {name = "peter"}
{ person | name = "George" }
{ particle | position = particle.position + particle.velocity }Control flow:
n = 5
if n < 0 then
"n is negative"
else if n > 0 then
"n is positive"
else
"n is zero"case aList of
[] -> "matches the empty list"
[x]-> "matches a list of exactly one item, " ++ toString x
x::xs -> "matches a list of at least one item whose head is " ++ toString xYou can pattern match in function definitions when there's only one case (single argument tuple):
area (width, height) =
width * height
area (6, 7) -- 42volume {width, height, depth} =
let
area = width * height
in
area * depth
volume { width = 3, height = 2, depth = 7 } -- 42Functions can be recursive:
fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
List.map fib [0..8] -- [1, 1, 2, 3, 5, 8, 13, 21, 34]Type signature for functions:
double : Int -> Int
double x = x * 2
List.map : (a -> b) -> List a -> List bType signature for records:
origin : { x : Float, y : Float, z : Float }
origin =
{ x = 0, y = 0, z = 0 }Type alias:
type alias Point3D =
{ x : Float, y : Float, z : Float }
otherOrigin : Point3D
otherOrigin =
Point3D 0 0 0
origin == otherOrigin -- TrueUnion types with tags:
type Direction =
North | South | East | West
type IntTree =
Leaf | Node Int IntTree IntTreeUnion types (and type aliases) can use type variables:
type Tree a =
Leaf | Node a (Tree a) (Tree a)
leftmostElement : Tree a -> Maybe a
leftmostElement tree =
case tree of
Leaf -> Nothing
Node x Leaf _ -> Just x
Node _ subtree _ -> leftmostElement subtreeModules export everything by default
module Name where
module Name (MyType, myValue) where -- exports MyType and myValue
-- Imports the Dict module and the Dict type, so your annotations don't have to
-- say Dict.Dict. You can still use Dict.insert.
import Dict exposing (Dict)
import Graphics.Collage as CLists:
[1..4]
[1,2,3,4]
1 :: [2,3,4]
1 :: 2 :: 3 :: 4 :: []Tooling
elm make MyFile.elm
# The reactor is a server that compiles and runs your files.
# Click the wrench next to file names to enter the time-travelling debugger!
elm reactor
elm repl
elm package install evancz/elm-htmlelm-format
- Course: Elm for Beginners
- Elm Conf
- create-elm-app
- Heroku buildpack and TODOMVC app
- Book: Elm in Action
- Learn X in Y Minutes
- Elm Syntax
- Union Types
- Video: Richard Feldman - Introduction to Elm (March 2016)
- Video: Confident Frontend with Elm (Jack Franklin) - Full Stack Fest 2016
- Video: Adventures in Elm
- Video: "Beyond Hello World and Todo Lists" by Ossi Hanhinen
- HTML to Elm (Tool)
- Learning FP the hard way: Experiences on the Elm language
- Learning Elm - Lucas Reis
- Elm: Concurrent FRP for Functional GUIs
- Building a simple admin interface using elm