a short introduction to Elm

Elm?

functional language
development platform
frontend architecture
ecosystem
community

ambition

no runtime exceptions

like, none

never

undefined should be a function

I'm joking

dont tweet that

the Elm language

functional

Haskell but simpler

type safety

compiles to JavaScript

functional

static types

purity

immutability

functional

module system

pattern matching

type aliases

functional

pipe operators

accessor functions

JavaScript interop

import Html exposing (text)

hello : String
hello =
    "Hello"

greet : String -> String
greet name =
    hello ++ ", " ++ name ++ "!"

main =
    text <| greet "World"

hello world

module Greetings exposing (greet)

hello : String
hello =
    "Hello"

greet : String -> String
greet name =
    hello ++ ", " ++ name ++ "!"
module Main exposing (main)

import Html exposing (text)
import Greetings exposing (greet)

main : Html.Html msg
main = 
    text <| greet "World"

module system

describeList : List String -> String
describeList list =
 case list of
    []      -> "No elements"
    [_]     -> "One element"
    [a,b]   -> "Two elements: " ++ a ++ " & " ++ b
    a::b::_ -> "A larger list"

pattern matching

answer : String -> Maybe Int
answer question =
    case question of
        "universe?" ->
            Just 42

        _ ->
            Nothing
type MyThing
  = AString String
  | AnInt Int
  | ATuple (String, Int)

unionFn : MyThing -> String
unionFn thing =
  case thing of
    AString s      -> "It was a string: " ++ s
    AnInt          -> "It was an int: " ++ toString i
    ATuple  (_, _) -> "It was a string and an int"

pattern matching union types

fingerprint : String -> List Char
fingerprint word =
    word
    |> String.toLower
    |> String.toList
    |> List.sort

fingerprint_ : String -> List Char
fingerprint_ word =
    List.sort 
    <| String.toList 
    <| String.toLower word 

pipe operators

> record = {foo="plop", bar="plap"}
{ foo = "plop", bar = "plap" } : { bar : String, foo : String }

> .foo record
"plop" : String

> .bar record
"plap" : String

> list = [{foo=1}, {foo=2}]
[{ foo = 1 },{ foo = 2 }] : List { foo : number }

> List.map .foo list
[1,2] : List number

accessor functions

port module Spelling exposing (..)


-- port for sending strings out to JavaScript
port check : String -> Cmd msg

-- port for listening for suggestions from JavaScript
port suggestions : (List String -> msg) -> Sub msg
app.ports.check.subscribe(function(word) {
    var suggestions = spellCheck(word);
    app.ports.suggestions.send(suggestions);
});

function spellCheck(word) {
    // have a real implementation!
    return [];
}

JavaScript interop

a development platform

platform

compiler

REPL

debugger

$ elm-make HelloWorld.elm --output HelloWorld.js

compiling

<-- index.html -->
<head>
    <script src="HelloWorld.js"></script>
</head>
<body>
    <script>Elm.Main.fullscreen()</script>
</body>
The definition of `greet` does not match its type annotation.

11| greet : String -> Int
12| greet name =
13|>    hello ++ ", " ++ name ++ "!"

The type annotation for `greet` says it always returns:

    Int

But the returned value (shown above) is a:

    String

Detected errors in 1 module.   

example compiler output

Cannot find variable `nane`

13|     hello ++ ", " ++ nane ++ "!"
                         ^^^^
Maybe you want one of the following?

    name
    tan
    Cmd.none
    Sub.none

Detected errors in 1 module.   

more sample compiler output

---- elm-repl 0.18.0 -----------------------------------------------------------
 :help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------------------------------------------------
> shows = []
[] : List a
> shows = [1]
[1] : List number
> shows = [1, 2, 3]
[1,2,3] : List number
> isEven n = n % 2 == 0
<function> : Int -> Bool
> shows |> List.filter isEven
[2] : List Int

the REPL in action

the embedded debugger in action

platform

npm integration

package manager

semantic versioning

code autoformat

$ npm install elm

npm package available

the package manager in action

semver ftw

code autoformat

an architecture

architecture

virtual dom

model

   view

     update

view : Html msg
view =
    div []
        [ h1 [] [ text "Title" ]
        , p [] [ text "Some text" ]
        , ul []
            [ li [] [ text "Bullet1" ]
            , li [] [ text "Bullet2" ]
            ]
        ]

virtual dom

<div>
    <h1>Title</h1>
    <p>Some text</p>
    <ul>
        <li>Bullet1</li>
        <li>Bullet2</li>
    </ul>
</div>

don't whine.

remember you have JSX

(               )

entryView : List Int -> Html msg
entryView entry =
    li [] [ text <| "Bullet" ++ toString entry ]


view : Model -> Html msg
view model =
    div []
        [ h1 [] [ text "Title" ]
        , p [] [ text "Some text" ]
        , ul [] <| List.map entry model.entries
        ]

abstract dom + functional language = <3

type Msg
    = NoOp
    | AddEntry String


type alias Model =
    { entries : List Int }


update : Msg -> Model -> Model
update msg model =
    case msg of
        NoOp ->
            model

        AddEntry entry ->
            { model | entries = entry :: model.entries }

a typical update function

formView : Html Msg
formView =
    p [] [ input [] [ Events.onInput AddEntry ] ]

a view triggering an event

an ecosystem

hundreds of packages

a friendly community

a supportive and beginner friendly slack channel

Questions?

or live demo if I've not been too long,

which is very unliely 

Elm

By Nicolas Perriault