Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Scenic City Summit 2017: Tame the frontend with...
Search
Jeremy Fairbank
July 28, 2017
Programming
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Scenic City Summit 2017: Tame the frontend with Elm
Jeremy Fairbank
July 28, 2017
More Decks by Jeremy Fairbank
See All by Jeremy Fairbank
Connect.Tech 2020: Advanced Cypress Testing
jfairbank
1
260
CodeMash 2020: Solving the Boolean Identity Crisis
jfairbank
1
230
CodeMash 2020: Practical Functional Programming
jfairbank
1
370
Connect.Tech 2019: Practical Functional Programming
jfairbank
0
450
Connect.Tech 2019: Solving the Boolean Identity Crisis
jfairbank
0
270
Lambda Squared 2019: Solving the Boolean Identity Crisis
jfairbank
0
200
All Things Open 2018: Practical Functional Programming
jfairbank
2
300
Connect.Tech 2018: Effective React Testing
jfairbank
1
230
Fluent Conf 2018: Building web apps with Elm Tutorial
jfairbank
2
950
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
520
Verilogで学ぶCPU自作入門.pdf
uyuki234
8
4k
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
190
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
120
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
160
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
230
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
120
FreeBSDでZabbixを動かす
kenkino
0
350
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
580
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
360
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
620
Featured
See All Featured
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
SEO for Brand Visibility & Recognition
aleyda
0
4.8k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
Designing Powerful Visuals for Engaging Learning
tmiket
1
590
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
920
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
ラッコキーワード サービス紹介資料
rakko
1
5.2M
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
930
WENDY [Excerpt]
tessaabrams
14
40k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
580
Transcript
Tame the frontend with Elm Jeremy Fairbank @elpapapollo / jfairbank
Tame the frontend with Elm Jeremy Fairbank @elpapapollo / jfairbank
Software is broken. We are here to fix it. Say
[email protected]
Happiness
None
✓ Easier to write code ✓ Easier to write tests
✓ Easier to refactor
elm
No runtime exceptions in practice.
No undefined is not a function
Fast
One framework. No fatigue. Update View Model Messages
elm
Functional
greet name = "Hello, " ++ name greet "Scenic City
Summit" -- Hello, Scenic City Summit
greet name = "Hello, " ++ name greet "Scenic City
Summit" -- Hello, Scenic City Summit
greet name = "Hello, " ++ name greet "Scenic City
Summit" -- Hello, Scenic City Summit
greet name = "Hello, " ++ name greet "Scenic City
Summit" -- Hello, Scenic City Summit Single Expression
greet name = "Hello, " ++ name greet "Scenic City
Summit" -- Hello, Scenic City Summit
greet name = "Hello, " ++ name greet "Scenic City
Summit" -- Hello, Scenic City Summit
Pure Data in Data out
Pure No side effects
Pure Predictable and Testable!
add x y = x + y add 2 3
== 5 add 2 3 == 5 add 2 3 == 5
add x y = x + y add 2 3
== 5 add 2 3 == 5 add 2 3 == 5
add x y = x + y add 2 3
== 5 add 2 3 == 5 add 2 3 == 5
Expressive Terse and declarative code
function doubleNumbers(numbers) { const doubled = []; const l =
numbers.length; for (let i = 0; i < l; i++) { doubled.push(numbers[i] * 2); } return doubled; } doubleNumbers([1, 2, 3, 4, 5]); // [2, 4, 6, 8, 10] Imperative
function doubleNumbers(numbers) { const doubled = []; const l =
numbers.length; for (let i = 0; i < l; i++) { doubled.push(numbers[i] * 2); } return doubled; } doubleNumbers([1, 2, 3, 4, 5]); // [2, 4, 6, 8, 10] Imperative ×
myList = [1, 2, 3, 4, 5] double n =
n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
myList = [1, 2, 3, 4, 5] double n =
n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
myList = [1, 2, 3, 4, 5] double n =
n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
myList = [1, 2, 3, 4, 5] double n =
n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
myList = [1, 2, 3, 4, 5] double n =
n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
myList = [1, 2, 3, 4, 5] double n =
n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
Curried Functions Building blocks
add x y = x + y add 1 2
-- 3 (add 1) 2 -- 3
add x y = x + y add 1 2
-- 3 (add 1) 2 -- 3
add x y = x + y add 1 2
-- 3 (add 1) 2 -- 3
add x y = x + y add 1 2
-- 3 (add 1) 2 -- 3 New function created
increment = add 1 increment 2 -- 3 increment 41
-- 42
increment = add 1 increment 2 -- 3 increment 41
-- 42
increment = add 1 increment 2 -- 3 increment 41
-- 42
Pipes Compose functions with expressive chaining
greet name = "Hello, " ++ name exclaim phrase =
phrase ++ "!" excitedGreeting name = exclaim (greet (String.toUpper name))
greet name = "Hello, " ++ name exclaim phrase =
phrase ++ "!" excitedGreeting name = exclaim (greet (String.toUpper name))
excitedGreeting name = name |> String.toUpper |> greet |> exclaim
excitedGreeting "Tucker"
excitedGreeting name = name |> String.toUpper |> greet |> exclaim
excitedGreeting "Tucker"
"Tucker" |> String.toUpper |> greet |> exclaim
|> String.toUpper "Tucker" |> greet |> exclaim
"TUCKER" |> greet |> exclaim
|> greet "TUCKER" |> exclaim
"Hello, TUCKER" |> exclaim
|> exclaim "Hello, TUCKER"
"Hello, TUCKER!"
No Runtime Exceptions
Strong Static Types life : Int life = 42 greeting
: String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
Strong Static Types life : Int life = 42 greeting
: String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
Strong Static Types life : Int life = 42 greeting
: String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
Strong Static Types life : Int life = 42 greeting
: String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
Strong Static Types life : Int life = 42 greeting
: String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
greet : String -> String greet name = "Hello, "
++ name add : Int -> Int -> Int add x y = x + y
greet : String -> String greet name = "Hello, "
++ name add : Int -> Int -> Int add x y = x + y
greet : String -> String greet name = "Hello, "
++ name add : Int -> Int -> Int add x y = x + y
greet : String -> String greet name = "Hello, "
++ name add : Int -> (Int -> Int) add x y = x + y
The 2nd argument to function `add` is causing a mismatch.
7| add 2 "3" ^^^ Function `add` is expecting the 2nd argument to be: Int But it is: String Compile time static type checks
Immutable Data Safe and Consistent
dog : { name : String, age : Int }
dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
dog : { name : String, age : Int }
dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
dog : { name : String, age : Int }
dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
dog : { name : String, age : Int }
dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
haveBirthday dog = { dog | age = dog.age +
1 } dog = { name = "Tucker", age = 11 } olderDog = haveBirthday dog olderDog.age -- 12 olderDog.name -- "Tucker" dog.age -- 11 dog.name -- "Tucker" Create New Data
haveBirthday dog = { dog | age = dog.age +
1 } dog = { name = "Tucker", age = 11 } olderDog = haveBirthday dog olderDog.age -- 12 olderDog.name -- "Tucker" dog.age -- 11 dog.name -- "Tucker" Create New Data
haveBirthday dog = { dog | age = dog.age +
1 } dog = { name = "Tucker", age = 11 } olderDog = haveBirthday dog olderDog.age -- 12 olderDog.name -- "Tucker" dog.age -- 11 dog.name -- "Tucker" Create New Data
haveBirthday dog = { dog | age = dog.age +
1 } dog = { name = "Tucker", age = 11 } olderDog = haveBirthday dog olderDog.age -- 12 olderDog.name -- "Tucker" dog.age -- 11 dog.name -- "Tucker" Create New Data
haveBirthday dog = { dog | age = dog.age +
1 } dog = { name = "Tucker", age = 11 } olderDog = haveBirthday dog olderDog.age -- 12 olderDog.name -- "Tucker" dog.age -- 11 dog.name -- "Tucker" Create New Data
haveBirthday dog = { dog | age = dog.age +
1 } dog = { name = "Tucker", age = 11 } olderDog = haveBirthday dog olderDog.age -- 12 olderDog.name -- "Tucker" dog.age -- 11 dog.name -- "Tucker" Create New Data
Custom Types Domain-specific code
type alias Dog = { name : String , age
: Int , breed : Breed } type Breed = Sheltie | Poodle
type alias Dog = { name : String , age
: Int , breed : Breed } type Breed = Sheltie | Poodle
type alias Dog = { name : String , age
: Int , breed : Breed } type Breed = Sheltie | Poodle Union Type
dog : Dog dog = { name = "Tucker" ,
age = 11 , breed = Sheltie }
dog : Dog dog = { name = "Tucker" ,
age = 11 , breed = Sheltie }
dog : Dog dog = { name = "Tucker" ,
age = 11 , breed = Sheltie }
dog : Dog dog = { name = "Tucker" ,
age = 11 , breed = Shelty } Misspelled. Won’t compile!
No null or undefined
type Maybe a = Just a | Nothing
type Maybe a = Just a | Nothing Wraps the
successful value
type Maybe a = Just a | Nothing Wraps the
successful value Type Variable
type Maybe a = Just a | Nothing Represents no
result or missing value
type Maybe a = Just a | Nothing Either I
have Just the value a, or I have Nothing.
divide : Float -> Float -> Maybe Float divide x
y = if y == 0 then Nothing else Just (x / y) divide 4 2 -- Just 2 divide 4 0 -- Nothing
divide : Float -> Float -> Maybe Float divide x
y = if y == 0 then Nothing else Just (x / y) divide 4 2 -- Just 2 divide 4 0 -- Nothing
divide : Float -> Float -> Maybe Float divide x
y = if y == 0 then Nothing else Just (x / y) divide 4 2 -- Just 2 divide 4 0 -- Nothing
divide : Float -> Float -> Maybe Float divide x
y = if y == 0 then Nothing else Just (x / y) divide 4 2 -- Just 2 divide 4 0 -- Nothing
divide : Float -> Float -> Maybe Float divide x
y = if y == 0 then Nothing else Just (x / y) divide 4 2 -- Just 2 divide 4 0 -- Nothing
divide : Float -> Float -> Maybe Float divide x
y = if y == 0 then Nothing else Just (x / y) divide 4 2 -- Just 2 divide 4 0 -- Nothing
case divide 4 2 of Just n -> "Result is
" ++ (toString n) Nothing -> "No Result"
case divide 4 2 of Just n -> "Result is
" ++ (toString n) Nothing -> "No Result"
case divide 4 2 of Just n -> "Result is
" ++ (toString n) Nothing -> "No Result"
case divide 4 2 of Just n -> "Result is
" ++ (toString n) Nothing -> "No Result"
case divide 4 2 of Just n -> "Result is
" ++ (toString n) -- Nothing -> -- "No Result"
Exhaustive matching This `case` does not have branches for all
possibilities. 21|> case divide 4 2 of 22|> Just n -> 23|> "Result is " ++ (toString n) You need to account for the following values: Maybe.Nothing Add a branch to cover this pattern!
Update View Model Messages The Elm Architecture
model Update View
model Update View VDOM
model Update View
model Update View
model Update View
model Update View
model Update View
model Update View VDOM
Demos The Elm Architecture in Action
Getting Started • elm-lang.org • elm-lang.org/examples • guide.elm-lang.org • www.elm-tutorial.org
• builtwithelm.co • Slack • elmlang.herokuapp.com
Thanks! Jeremy Fairbank @elpapapollo / jfairbank Slides: bit.ly/scs-elm