(elm)troduction
An introduction to elm-lang
What is elm
- 6 years old language (2012)
- Compile to JS
- Front-end focus
- Simplicity focus
- FRP focus
CHARACTERISTICS
- Functional
- ML syntax
- Immutability
- Pure functions
- Strong type system, but:
- No typeclasses
- No higher kinded types
- Functional reactive programming
DO I REALLY NEED TO LEARN A NEW LANGUAGE?
LET’S JUST USE JAVASCRIPT!
ES6 + Babel + Webpack + React + Redux + Immutable
Elm
or or or or
Typescript Gulp Cycle.js + RxJS seamless
Not even close
Elm Make
The compiler that talks to you
No Runtime Exceptions
No Runtime Exceptions
A little more syntax
-- isNotEven = not . isEven
isNotEven = not << isEven
isNotEven_ = isEven >> not
-- let lastChar = head $ toList $ reverse "foobar"
let lastChar = head <| toList <| reverse "foobar"
dot =
scale 2 (move (20,20) (filled blue (circle 10)))
dot_ =
circle 10
|> filled blue
|> move (20,20)
|> scale 2
Records
carolina =
{ name = "Carolina de Jesus"
, age = 62
}
abdias =
{ name = "Abdias Nascimento"
, age = 97
}
people =
[ carolina
, abdias
]
carolina.name
.name carolina
List.map .name people
-- ["Carolina de Jesus", "Abdias Nascimento"]
ELM-REPL
Just a regular REPL
ELM-PACKAGE
The best package manager ever
ENFORCED SEMVER
ENFORCED SEMVER
AUTOMATIC CHANGELOG
ENFORCED DOCS
ELM REACTOR
Awesome development flow
Elm Reactor
- Auto compile Elm
- Hot-swapping
- Time travel debugging
Example
THE ELM ARCHITECTURE

Model-View-Update

Model-View-Update
Concept | Elm | Redux |
---|---|---|
Application state | Model | State |
Application events | Message | Action |
Function that transforms the state | Update | Reducer |
talk is cheap, show me the code
module Counter exposing (..)
import Html exposing (..)
import Html.Events exposing (onClick)
import Html.Attributes exposing (style)
-- MODEL
type Msg
= Increment
| Decrement
model : Int
model =
0
...
Counter.elm
...
-- VIEW
view : Int -> Html.Html Msg
view model =
div []
[ button [ onClick Increment ] [ text "+" ]
, br [] []
, div [ countStyle ] [ text (toString model) ]
, br [] []
, button [ onClick Decrement ] [ text "-" ]
]
countStyle : Attribute msg
countStyle =
style
[ ( "font-size", "20px" )
, ( "font-family", "monospace" )
, ( "display", "inline-block" )
, ( "width", "50px" )
, ( "text-align", "center" )
]
...
Counter.elm
...
-- UPDATE
update : Msg -> Int -> Int
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
Counter.elm
module Main exposing (..)
import Html exposing (beginnerProgram)
import Counter exposing (model, view, update, Msg)
main : Program Never Int Msg
main =
beginnerProgram { model = model, view = view, update = update }
Main.elm
Elm Runtime

Commands

Commands

Subscriptions

Subscriptions

invention or discovery?
try to escape the Elm Architecture, I dare you!
ELM-TEST
Only for checking what the compiler can’t
ELM TEST
module Example exposing (..)
import ElmTest exposing (..)
tests : Test
tests =
suite "A Test Suite"
[ test "Addition" <|
assertEqual (3 + 7) 10
, test "This test should fail" <|
assert False
]
ELM TEST BDD STYLE
module ExampleBDD exposing (..)
import ElmTestBDDStyle exposing (..)
import Expect exposing (..)
import Test exposing (..)
tests : Test
tests =
describe "Example Test"
[ it "dds two numbers" <|
expect (3 + 7) to equal 10
, it "fails for non-sense stuff" <|
expect True toBe False
]
JavaScript interop
Avoid it at all costs
From JS to ELM
myapp.ports.addUser.send([
"Tom",
{ age: 32, job: "lumberjack" }
]);
myapp.ports.addUser.send([
"Sue",
{ age: 37, job: "accountant" }
]);
-- port for listening for addUser from JavaScript
port addUser : (String, UserRecord -> msg) -> Sub msg
From ELM to JS
myapp.ports.requestUser.subscribe(databaseLookup);
function databaseLookup(user) {
var userInfo = database.lookup(user);
myapp.ports.addUser.send(user, userInfo);
}
-- port for sending strings out to JavaScript
port requestUser : String -> Cmd msg
JS INTEROP
DON'T USE THIS
Get your hands dirty
Thank You
(elm)troduction
By Henk
(elm)troduction
- 171