Elm Programming Language

Andrew Schutt

Hello!

Dialects

Dialects

Dialects

Frameworks

Dialects

Frameworks

Packaging

Dialects

Frameworks

Packaging

Utilities

Dialect

Framework

Packaging

Utilities

It's all Elm!

What is Elm?

Elm

Created By @czaplic

compiles to

https://guide.elm-lang.org/install.html

compiles to


    > elm make Main.elm --output elm.js

Main.elm

elm.js

Functional

Pure Functions

Pure Functions

    
    > add 3 5 -- 8
    > add 3 5 -- 8
    > add 3 5 -- 8

Declarative



    var numbers = [1, 2, 3, 4, 5];

    function doubleNumbers (numbers) {
        const doubled = [];
        const l = numbers.length;
    
        for (let i = 0; i < l; i++) {
            doubled.push(numbers[i] * 2);
        };
    
        return doubled;
    };

Imperative Example


    myList = [1, 2, 3, 4, 5]
    
    double n = n * 2

    doubleNumbers list = 
        List.map double list

    doubleNumbers myList
    

Declarative Example

Immutable

By Ptelea - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=16572537

Why use Elm?

Performance

* https://elm-lang.org/blog/small-assets-without-the-headache

* https://elm-lang.org/blog/blazing-fast-html-round-two

Performance


    > elm make --optimize

"No runtime exceptions"

Compiler

Compiler Errors

Error Handling

Error Handling


    
    function fetchCatz() {
        return fetch('http://www.funnycatpix.com/')
               .then(r => r.json())
               .then(photo => { /* handle photo */ }); 
    }

    
    function fetchCatz() {
        return fetch('http://www.funnycatpix.com/')
               .then(r => r.json())
               .then(photo => { /* handle photo */ }); 
    }

Error Handling

No catch statement!


    
  fetchCatz : Cmd Msg 
  fetchCatz =
    Http.get
    { url = "http://www.funnycatpix.com/"
    , expect = Http.expectJson LoadCatz photoDecoder }

Error Handling

Strong Static Typing


    
    score : Int
    score = 0

    greeting : String
    greeting = "Hello!"    

    needCoffee : Bool
    needCoffee = True

    numbers : List
    numbers = [1, 2, 3, 4]

Static Types

By Melburnian - Own work, CC BY 2.5, https://commons.wikimedia.org/w/index.php?curid=1287428

Syntax and Features

Functions

Functions


    
    isNegative n = n < 0

Functions


    
    isNegative n = n < 0

    isNegative 4
    False

    isNegative -8
    True

    isNegative (-2 * -11)
    False

Anonymous Functions


    
    \n -> n < 0

    (\n -> n < 0) 4
    False

    (\n -> n < 0) -8
    True

    (\n -> n < 0) (-2 * -11)
    False

Function Currying


    
    add x y z = x + y + z

    add 1 2 3
    ((add 1) 2) 3

    add1 = add 1
    add2 = add1 2
    add2 3 -- 6
   

Currying

Piping


    
  format str = String.trim (String.repeat 4 (String.toUpper str))

Piping


    
    format str = 
        str
            |> String.toUpper
            |> String.repeat 4
            |> String.trim

Annotations

Annotations


    
    -- doubles ints and adds two results
    doSomething x y = 
        (x * 2) + (y * 2)

Annotations


    
    -- doubles ints and adds two results
    doSomething x y = 
        (x * 2) + (y * 2)

Annotations


    -- doubles ints and adds two results
    doSomething x y = 
        (x * 2.0) + (y * 2.0)

Annotations


    doSomething : Int -> Int -> Int
    doSomething x y = 
        (x * 2.0) + (y * 2.0)

Annotations


    doSomething : Float -> Float -> Float
    doSomething x y = 
        (x * 2.0) + (y * 2.0)

Lists

Lists


    
    numbers = [1, 2, 3, 4]

    strings = ["one", "two" "three", "four"]

    numsAndStrs = [1, "two", 3, "four"]

Lists


    
    numbers = [1, 2, 3, 4]

    strings = ["one", "two" "three", "four"]

    numsAndStrs = [1, "two", 3, "four"]

Records

Records


    
    album = 
        { title = "Rubber Soul"
        , artist = "The Beatles"
        , tracks = [1, 2, 3, 4, 5]
        }

    album.title
    "Rubber Soul" : String 

Immutable


    
    album.title = "Abbey Road"


    { album | title = "Abbey Road" }

    { title = "Abbey Road"
    , artist = "The Beatles"
    , tracks = [1, 2, 3, 4, 5] 
    }

Immutable


    album = { title = "Rubber Soul", ... }
    abbeyRoad = { album | title = "Abbey Road" }

    abbeyRoad
    { title = "Abbey Road", ... }

    album
    { title = "Rubber Soul", ... }

Tuples

Tuples

    
    (1)

    (1, "two")

    (1, "two", 3.0)

    (1, "two", 3.0, Four)

Type Aliases

Type Aliases


    type alias Pet = 
        { name : String
        , breed : String
        , age : Int
        }

    dog = Pet "Bunsen" "Dog" 0

    puppyBirthday : Pet -> Int
    puppyBirthday pet =
        pet.age + 1

    { dog | age = puppyBirthday dog }
    { age = 1, breed = "Dog", name = "Bunsen" }

Type Aliases


    type alias Pet = 
        { name : String
        , breed : String
        , age : Int
        }

    dog = Pet "Bunsen" "Dog" 0

    puppyBirthday : Pet -> Int
    puppyBirthday pet =
        pet.age + 1

    { dog | age = puppyBirthday dog }
    { age = 1, breed = "Dog", name = "Bunsen" }

Type Aliases


    type alias Pet = 
        { name : String
        , breed : String
        , age : Int
        }

    dog = Pet "Bunsen" "Dog" 0

    puppyBirthday : Pet -> Int
    puppyBirthday pet =
        pet.age + 1

    { dog | age = puppyBirthday dog }
    { age = 1, breed = "Dog", name = "Bunsen" }

Type Aliases


    type alias Pet = 
        { name : String
        , breed : String
        , age : Int
        }

    dog = Pet "Bunsen" "Dog" 0

    puppyBirthday : Pet -> Int
    puppyBirthday pet =
        pet.age + 1

    { dog | age = puppyBirthday dog }
    { age = 1, breed = "Dog", name = "Bunsen" }

Union Types

Union Types


    type Breed = Dog | Cat | Parrot    

    type alias Pet = 
        { name : String
        , breed : String
        , age : Int
        }

    

Union Types


    type Breed = Dog | Cat | Parrot    

    type alias Pet = 
        { name : String
        , breed : Breed
        , age : Int
        }

    

Union Types



        dog = Pet "Bunsen" "Dog" 0



        dog = Pet "Bunsen" Dog 0

Case Statements

Case Statements


    dog = Pet "Bunsen" Dog 1
    cat = Pet "Beaker" Cat 6

    talk : Pet -> String
    talk pet =
      case pet of
            Dog ->
              "Bark! Bark!"

            Cat ->
              "Meow! Meow!"
        
        

Case Statements


    dog = Pet "Bunsen" Dog 1
    cat = Pet "Beaker" Cat 6

    talk : Pet -> String
    talk pet =
      case pet of
            Dog ->
              "Bark! Bark!"

            Cat ->
              "Meow! Meow!"
        
        

Case Statements


    dog = Pet "Bunsen" Dog 1
    cat = Pet "Beaker" Cat 6

    talk : Pet -> String
    talk pet =
      case pet of
            Dog ->
              "Bark! Bark!"

            Cat ->
              "Meow! Meow!"
        
        

Case Statements



    talk : Pet -> String
    talk pet =
      case pet of
            Dog ->
              "Bark! Bark!"

            Cat ->
              "Meow! Meow!"

            Parrot ->
              "Squawk! Squawk!
        
        

Maybe Type

Maybe Type


    
    type Maybe a  
        = Just a
        | Nothing

Maybe Type


    
    type Maybe a  
        = Just a
        | Nothing

    Just 3.14 : Maybe Float
    Just "hi" : Maybe String
    Just True : Maybe Bool
    Nothing   : Maybe a

Tooling

Tooling

  • Packages   -> elm install
  • Compiler   -> elm make
  • REPL       -> elm repl
  • Dev Server -> elm reactor
    
  • Framework  -> Elm Architecture

Elm Architecture

Elm Architecture

  • Model - state of application
  • Update - update your state
  • View - display your state

Elm Architecture

Model

Elm Architecture

View

Model

Elm Architecture

View

Model

Elm Architecture

View

Model

Update

Elm Architecture

View

Model

Update

Elm Architecture

View

Model

Update

Elm Architecture

View

Model

Update

Elm Runtime

Elm Architecture

    
    -- MODEL
    
    type alias Model = { ... }
    
    -- UPDATE
    
    type Msg = Reset | ...
    
    update : Msg -> Model -> Model
    update msg model =
      case msg of
        Reset -> ...
        ...
    
    -- VIEW
    
    view : Model -> Html Msg
    view model =
      ...

Elm Architecture

    
    -- MODEL
    
    type alias Model = { ... }
    
    -- UPDATE
    
    type Msg = Reset | ...
    
    update : Msg -> Model -> Model
    update msg model =
      case msg of
        Reset -> ...
        ...
    
    -- VIEW
    
    view : Model -> Html Msg
    view model =
      ...

Elm Architecture

    
    -- MODEL
    
    type alias Model = { ... }
    
    -- UPDATE
    
    type Msg = Reset | ...
    
    update : Msg -> Model -> Model
    update msg model =
      case msg of
        Reset -> ...
        ...
    
    -- VIEW
    
    view : Model -> Html Msg
    view model =
      ...

Elm Architecture

    
    -- MODEL
    
    type alias Model = { ... }
    
    -- UPDATE
    
    type Msg = Reset | ...
    
    update : Msg -> Model -> Model
    update msg model =
      case msg of
        Reset -> ...
        ...
    
    -- VIEW
    
    view : Model -> Html Msg
    view model =
      ...

Counter Example

JavaScript Interop

JavaScript Interop


    > elm make src/Main.elm

    > elm make src/Main.elm --output=main.js

JavaScript Interop


    <!DOCTYPE HTML>
    <html>
        <head>
          <meta charset="UTF-8">
          <title>Main</title>
          <script src="main.js"></script>
        </head>
    
        <body>
          <div id="elm"></div>
          <script>
              var app = Elm.Main.init({
                node: document.getElementById('elm')
              });
          </script>
        </body>
    </html>

JavaScript Interop


    <!DOCTYPE HTML>
    <html>
        <head>
          <meta charset="UTF-8">
          <title>Main</title>
          <script src="main.js"></script>
        </head>
    
        <body>
          <div id="elm"></div>
          <script>
              var app = Elm.Main.init({
                node: document.getElementById('elm')
              });
          </script>
        </body>
    </html>

Flags


    var app = Elm.Main.init({
      node: document.getElementById('elm')
    });

    var app = Elm.Main.init({
      node: document.getElementById('elm'),
      flags: Date.now()
    });

Ports

Drawbacks

New Language

Small Package Ecosystem

Hiring

Lots of code

Future of Elm

Future of Elm

Future of Elm

Future of Elm

Web Assembly

Additional Info

Resources

  • elm-lang.org
  • guide.elm-lang.org
  • Slack
    • elmlang.herokuapp.com
  • elm-tutorial
  • Elm In Action
    • by Richard Feldman
  • Programming Elm
    • by Jeremy Fairbanks

By Jim.henderson - Own work, CC0, https://commons.wikimedia.org/w/index.php?curid=15909555

Questions?

Thank you!

Elm Programming Language

By Andrew Schutt

Elm Programming Language

a presentation for Iowa Code Camp as an introduction to the Elm Programming Language

  • 1,529