Elm: 

the best of functional programming in your browser

Who's this guy?

  • Cameron Alexander
  • github/twitter: @emptyflash
  • iOffice

THE HYPE

It's fast

It's reliable

It's got cool stuff

Crazy helpful error messages

What is Elm?

Elm is a programming language that compiles to JavaScript

Elm is functional

Elm is statically and strongly typed

Elm is reactive

Elm is in the ML family

Haskell

Elm

OCaml

Why wouldn't I just use X?

The community is great

Elm isn't as scary

Elm is constantly evolving

The Basics

var numbers = [1, 2, 3];

var first = numbers[0];

var doubleFirst = first * 2;
numbers =
    [ 1, 2, 3 ]

first =
    List.head numbers

doubleFirst =
    first * 2

JavaScript

Elm

var numbers = [];

var first = numbers[0];

var doubleFirst = first * 2;

// doubleFirst = NaN
numbers =
    []

first =
    List.head numbers

doubleFirst =
    first * 2

-- doubleFirst = ???

JavaScript

Elm

Buuuuut.....

Elm is different

What's a maybe?

numbers = 
    []

first =
    Maybe.withDefault 0 (List.head numbers)

doubleFirst =
    first * 2

Here's how you handle it

import Html exposing (text)

main =
  text "Hello, World!"

Hello, World!

add: Int -> Int -> Int
add x y =
    x + y


\x y -> x - y


added =
    add 1 2

How about some functions

record =
  { key = "value"
  , key2 = "value2"
  }

record.key  -- returns "value"

.key record -- returns "value

{ record | key2 = "new value" }



list = [1, 2, 3]

List.head list  -- returns Just 1

List.length list  -- returns 3


recordsList = [record, record, record]

List.map .key recordList  -- returns ["value", "value", "value"]

Data structures?

if powerLevel > 9000 then
  "*crushes scouter*"
else if powerLevel > 8000 then
  "still pretty good"
else
  "meh"

If statements

volume width height depth =
  let
    area = width * height
  in
    area * depth

Intermediate values

case aList of
    [] -> "matches the empty list"
    [x]-> "matches a list of one item, " ++ toString x
    _ -> "matches anything else"

Pattern matching

case List.head someList of
  Just x -> "The first element is " ++ (toString x)
  Nothing -> "The list was empty."

Pattern matching with Maybes

type Fruit = Apple | Orange

apple = Apple

case apple of
    Apple -> "Value is Apple"
    Orange -> "Value is Orange"

Union types

type Wallet = Money Float | Broke

richDude = Wallet 1000000.0

cameron = Broke

case richDude of
    Money amount -> "This person has $" ++ (toString amount)
    Broke -> "This person is broke"

Union types with a value

type Maybe a = Just a | Nothing

maybe =
    Just 42

case maybe of
    Just x -> "Our maybe had the value of " ++ x
    Nothing -> "Our maybe was nothing"

Generic union types

multiply a b =
  a * b

double =
  multiply 2

subtract a b =
  a - b

subtractOne =
  subtract 1

doubleThenSubtractOne =
  double >> subtractOne

subtractOneThenDouble =
  double << subtractOne

Function composition

five =
  5

add a b =
  a + b

double a =
  a * 2

fourteen =
  five
    |> double
    |> add 4

Forward application

five =
  5

add a b =
  a + b

double a =
  a * 2

fourteen =
  add 4 << double <| five

Backward application

origin : { x : Float, y : Float }
origin =
  { x = 0
  , y = 0
  }

type alias Point =
  { x : Float
  , y : Float
  }

otherOrigin =
  Point 1 1

hypotenuse : Point -> Float
hypotenuse {x,y} =
  sqrt (x^2 + y^2)

Record types

type alias Positioned a =
  { a | x : Float, y : Float }

type alias Named a =
  { a | name : String }

type alias Moving a =
  { a | velocity : Float, angle : Float }

lady : Named { age:Int }
lady =
  { name = "Lois Lane"
  , age = 31
  }

dude : Named (Moving (Positioned {}))
dude =
  { x = 0
  , y = 0
  , name = "Clark Kent"
  , velocity = 42
  , angle = degrees 30
  }

Extensible records

module Name (MyType, myValue)

type MyType = Something | OtherThing

myValue =
  Something

Modules

-- No module means Main

import Name

myValue =
  Name.myValue


-- OR

import Name exposing (myValue)


-- OR

import Name as N

myValue =
  N.myValue

Questions so far?

Advanced stuff

Signals

Like callbacks, but not

PUB SUB

Tasks

Like promises, but not

Tasks

Task.map 
  (\s -> s + " tasks") 
  Task.succeed "Hello"

Task.succeed 2 
  `andThen` (\n -> Task.succeed (n + 2))
$q.resolve("Hello").then(function(string) {
    return string + " promises";
});

$q.resolve(2).then(function(n) {
    return $q.resolve(n + 2);
});

The Elm Architecture

Like a framework, but not

Questions?

Elm for Functional Programmers

By Cameron Alexander

Elm for Functional Programmers

  • 831