Yet Another Introduction
Elm Lang
Live without side effects
What is Elm Lang
Elm is a functional language that compiles to JavaScript.
No combination of JS libraries can ever give you this, yet it is all free and easy in Elm.
No Runtime Exceptions *
Great Performance
Static types
Algebraic data types (ADT)
Immutability
Anonymous records
Parametric polymorphism
Compile to Javascript
Why Elm?
Hello world
import Html exposing (span, text)
import Html.Attributes exposing (style)
main =
span
[style [("color", "red")]]
[text "Hello, World!"]
Easy as ABC
Syntax
True : Bool
False : Bool
42 : number -- Int or Float depending on usage
3.14 : Float
'a' : Char
"abc" : String
Literals
True && not (True || False)
(2 + 4) * (4^2 - 9)
"abc" ++ "def"
Typical manipulation of literals
(0, True, 'z', "abc")
(,) 1 2 == (1,2)
(,,,) 1 True 'a' [] == (1,True,'a',[])
Tuples
[1,2,3,4]
1 :: [2,3,4]
1 :: 2 :: 3 :: 4 :: []
['a', 'b', 'c']
["a", "b", "c"]
Lists
square n =
n^2
hypotenuse a b =
sqrt (square a + square b)
distance (a,b) (x,y) =
hypotenuse (a-x) (b-y)
Functions
multiply a b = a * b
multiplyByThree = multiply 3
Partial Function Application
Operators are Functions Too
(++) [1, 2, 3] [4, 5, 6]
List.foldl (*) 1 [1, 2, 3, 4, 5]
Union Types
Type Annotation
-- function name : 1st arg type -> 2nd arg type -> return type
fnc : Int -> List Int -> Int
type Movement = Right | Left | Stop
type Maybe a = Just a | Nothing
type Result e a = Failure e | Success a
type Tree a = Tree (Tree a) a (Tree a) | Leaf
point = -- create a record
{ x = 3, y = 4 }
point.x -- access field
List.map .x [point,{x=0,y=0}] -- field access function
{ point | x = 6 } -- update a field
{ point | -- update many fields
x = point.x + 1,
y = point.y + 1
}
dist {x,y} = -- pattern matching on fields
sqrt (x^2 + y^2)
type alias Location = -- type aliases for records
{ line : Int
, column : Int
}
Syntax. Records
primitiveCount number =
case number of
1 -> "one"
2 -> "two"
3 -> "three"
4 -> "four"
_ -> "many"
case maybe of
Just xs -> xs
Nothing -> []
case xs of
hd::tl -> Just (hd,tl)
[] -> Nothing
case n of
0 -> 1
1 -> 1
_ -> fib (n-1) + fib (n-2)
Pattern Matching in Case Expression
module MyModule exposing (..)
-- qualified imports
import List -- List.map, List.foldl
import List as L -- L.map, L.foldl
-- open imports
import List exposing (..) -- map, foldl, concat, ...
import List exposing ( map, foldl ) -- map, foldl
import Maybe exposing ( Maybe ) -- Maybe
import Maybe exposing ( Maybe(..) ) -- Maybe, Just, Nothing
import Maybe exposing ( Maybe(Just) ) -- Maybe, Just
Syntax. Modules
Let's practice a little bit
The Elm Architecture
The Basic Pattern
The logic of every Elm program will break up into three cleanly separated parts
Model
Update
View
Beginner program
Beginner program
import Html exposing (Html, beginnerProgram)
main : Program Never model msg
main =
beginnerProgram
{ model = ... -- : model
, view = ... -- : model -> Html msg
, update = ... -- : msg -> model -> model
}
import Html exposing (text)
main =
Html.beginnerProgram
{ model = ()
, view = always (text "Hello World!")
, update = always identity
}
-- always : a -> b -> a
-- identity : a -> a
Beginner program example
Beginner program example
import Html exposing (text, div, button)
import Html.Events exposing (onClick)
type Msg = Inc | Dec
model = 0
view model = div []
[ button [ onClick Dec ] [ text "-" ]
, text <| toString model
, button [ onClick Inc ] [ text "+" ] ]
update msg model =
case msg of
Inc -> model + 1
Dec -> model - 1
main = Html.beginnerProgram
{ model = model
, view = view
, update = update
}
Beginner program
can't control side effects
Side effects
- Random value
- Http requests
- Time
- Websockets communication
- Mouse behavior
- etc.
Program
Program
import Html exposing (program)
program :
{ init : (model, Cmd msg)
, view : model -> Html msg
, update : msg -> model -> (model, Cmd msg)
, subscriptions : model -> Sub msg
}
-> Program Never model msg
Program Example with Sub usage
type alias Model = Time
init : (Model, Cmd Msg)
init =
(0, Cmd.none)
type Msg
= Tick Time
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Tick newTime ->
(newTime, Cmd.none)
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every second Tick
view : Model -> Html Msg
view model =
Html.text (toString model)
Program Example with Cmd usage
type alias Model = Int
type Msg
= GenerateNumber
| SetNumber Int
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
GenerateNumber ->
( model, Random.generate SetNumber (Random.int 1 6) )
SetNumber number ->
( number, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ h1 [] [ text (toString model) ]
, button [ onClick GenerateNumber ] [ text "Generate" ]
]
But what about complex Applications?
We do not think in terms of reusable components.
Instead, we focus on reusable functions. It is a functional language after all!
elm-repl — play with Elm expressions
elm-reactor — get a project going quickly
elm-make — compile Elm code directly
elm-package — download packages
Elm Tooling
Elm package repository (semver guarantee)
Time traveling debugger
Elm Ecosystem
$ elm-make Main.elm --output elm.js
Elm Embeding
<div id="elm-code-is-loaded-here"></div>
<script src="elm.js"></script>
<script>
Elm.Main.embed(document.getElementById("elm-code-is-loaded-here"));
</script>
Elm Bundle
Framework sizes
$ ls -lhS
566K Jan 4 22:03 angular2.min.js
563K Jan 4 22:05 angular2.0.0-beta.0-all.umd.min.js
486K Jan 4 21:50 ember.1.13.8.min.js
435K Jan 4 21:48 ember.2.2.0.min.js
205K Jan 4 22:06 angular2.0.0-beta.0-Rx.min.js
144K Jan 4 21:59 react-with-addons-0.14.5.min.js
143K Jan 4 21:46 angular.1.4.5.min.js
132K Jan 4 21:56 react-0.14.5.min.js
121K Jan 4 21:35 angular.1.3.2.min.js
5.3K Jan 4 22:00 redux-3.0.5.min.js
706B Jan 4 21:57 react-dom-0.14.5.min.js
63K Oct 13 03:02 vue-2.0.3.min.js
# 2017
91K Dec 27 12:24 react-dom-16.2.0.production.min.js
6.5K Dec 27 12:22 react-16.2.0.production.min.js
$ elm-make Main.elm --output=main.js
$ uglifyjs ./main.js -o main.min.js -c -m
$ ls -lhS
189K Apr 7 15:32 main.js
65K Apr 7 15:37 main.min.js
Hello world Elm App size
Resources
Workshop time!
Elm-lang. Yet Another Introduction
By Ufocoder
Elm-lang. Yet Another Introduction
Elm-lang. Yet Another Introduction
- 1,627