KEMBAR78
Elm: frontend code without runtime exceptions | PDF
Frontend code without runtime
exceptions
@PietroGrandi3D
elm
1 / 41
Pietro Grandi
1. Frontend developer
2. Write on pietrograndi.com
3. Born as 3D Artist
Hi!
2 / 41
Runtime exception
3 / 41
When does it happen?
calling unexisting methods
var aString = 1;
var first = aString.slice(0,1);
Runtime exception
4 / 41
When does it happen?
calling unexisting methods
var aString = 1;
var first = aString.slice(0,1);
your program expects a type to be a di erent one
Runtime exception
5 / 41
You discover it by the time
you run that specific code
6 / 41
What causes it?
1. inconsistent data from external sources
Runtime exception
7 / 41
What causes it?
1. inconsistent data from external sources
2. error loading dependencies
Runtime exception
8 / 41
What causes it?
1. inconsistent data from external sources
2. error loading dependencies
3. bugs
Runtime exception
9 / 41
What causes it?
1. inconsistent data from external sources
2. error loading dependencies
3. bugs
we can control bugs
Runtime exception
10 / 41
Can't I prevent bugs?
you should be able to
a simple JS bug
function contains(c, s) {
var index = s.indexOf(c);
return index > -1;
}
console.log(contains("hi", "there")); // false
console.log(contains("hi", "hi!")); // true
console.log(contains("hi", 1)); // TypeError: s.indexOf is
// not a function
Bugs
11 / 41
Bring back type checking
apply defensive techniques
check against type
function contains(c, s) {
var index = typeof s === 'string' ? s.indexOf(c) : -1;
return index > -1;
}
console.log(contains("hi", "there")); // false
console.log(contains("hi", "hi!")); // true
console.log(contains("hi", 1)); // false
Bugs
12 / 41
Figthing bugs in JS
use a linter
put runtime checks/assertions
handle corner cases
write more tests
try to rule your growing codebase
Bugs
13 / 41
Isn't this a job for a
compiler?
14 / 41
Catch'em at compile time
static type checking
non-nullable types
no implicit casts
referential transparency
Bugs
15 / 41
How does Elm behave?
contains c s =
(List.length (String.indexes c s)) > 0
v = contains "hi" 1
Bugs
runnable example here 16 / 41
Doesn't compile
contains c s =
(List.length (String.indexes c s)) > 0
v = contains "hi" 1
Bugs
runnable example here 17 / 41
Cool.
What is Elm?
18 / 41
What is Elm
functional language
declarative UI design
ML-like syntax
immutable data structures
statically and strongly typed
Elm
19 / 41
Strong typing
if 0 then
doStuff
else
differentStuff
Elm
20 / 41
Immutable data structures
a = 2
a = a + 3
Elm
21 / 41
Functional
first-class functions
all functions can be partially applied
contains c s =
(List.length (String.indexes c s)) > 0
containsH = contains "h" -- a new function
all functions always return
Elm
22 / 41
Features
compiles to Javascript
follows Elm Architecture
inference engine
enforces semantic versioning
Javascript interoperability
Elm
23 / 41
Elm Architecture?
24 / 41
The pattern
model: the state
update: modify your state
view: show your state
Elm architecture
25 / 41
The pattern
model: the state
update: modify your state
view: show your state
update changes model using messages
Elm architecture
26 / 41
The counter!
main =
beginnerProgram { model = 0, view = view, update = update }
type Msg = Increment | Decrement
update msg model =
case msg of
Increment -> model + 1
Decrement -> model - 1
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (toString model) ]
, button [ onClick Increment ] [ text "+" ]
]
A trivial example
try it live! 27 / 41
Looks like Redux
Elm architecture
actually, Redux has been inspired by the Elm architecture... 28 / 41
Looks like Redux
it is part of the language
no plugins, libraries, hacks
just one way to go
Elm architecture
actually, Redux has been inspired by the Elm architecture... 29 / 41
The virtual DOM
evaluate what changes
render what is needed
lazy evaluation
Performances
30 / 41
JS output
use arrays instead of dictionaries
references instead of looking up
fully initialize objects
hooks to requestAnimationFrame to save work
Performances
31 / 41
How does it compare to
competitors?
32 / 41
source 33 / 41
Sorry, I lied
You can still get runtime exceptions
34 / 41
Sorry, I lied
You can still get runtime exceptions
If you use Javascript.
35 / 41
Manual bootstrap
var mountNode = document.getElementById('main');
var myApp = Elm.Main.embed(mountNode);
can act on a subset of the page
allows for slow integration
can build a small module
Javascript interoperability
36 / 41
Ports
get data from JS code
send data to JS code
typed ports
runtime assertions
Javascript interoperability
37 / 41
Inbound ports
define the port
type alias Move = (Float, Float)
port scroll : (Move -> msg) -> Sub msg
send data from JS code
myApp.ports.scroll.send([scroll, newScroll]);
Javascript interoperability
code from MaltaJS Elm app 38 / 41
Outbound ports
define the port
port todoListChanges : (List TodoItem) -> Cmd msg
listen for data
myApp.ports.todoListChanges.subscribe((updatedTodoList) => { /*...*/ })
Javascript interoperability
code from TodoMVC done in Elm 39 / 41
Elm Package Manager
forces documentation with a precise format
must document every public item
automatic semantic versioning
Package system
40 / 41
References:
Elm website
Elm slack community
Elm architecture
Move fast and don't break things
Thank you!
41 / 41

Elm: frontend code without runtime exceptions

  • 1.
    Frontend code withoutruntime exceptions @PietroGrandi3D elm 1 / 41
  • 2.
    Pietro Grandi 1. Frontenddeveloper 2. Write on pietrograndi.com 3. Born as 3D Artist Hi! 2 / 41
  • 3.
  • 4.
    When does ithappen? calling unexisting methods var aString = 1; var first = aString.slice(0,1); Runtime exception 4 / 41
  • 5.
    When does ithappen? calling unexisting methods var aString = 1; var first = aString.slice(0,1); your program expects a type to be a di erent one Runtime exception 5 / 41
  • 6.
    You discover itby the time you run that specific code 6 / 41
  • 7.
    What causes it? 1.inconsistent data from external sources Runtime exception 7 / 41
  • 8.
    What causes it? 1.inconsistent data from external sources 2. error loading dependencies Runtime exception 8 / 41
  • 9.
    What causes it? 1.inconsistent data from external sources 2. error loading dependencies 3. bugs Runtime exception 9 / 41
  • 10.
    What causes it? 1.inconsistent data from external sources 2. error loading dependencies 3. bugs we can control bugs Runtime exception 10 / 41
  • 11.
    Can't I preventbugs? you should be able to a simple JS bug function contains(c, s) { var index = s.indexOf(c); return index > -1; } console.log(contains("hi", "there")); // false console.log(contains("hi", "hi!")); // true console.log(contains("hi", 1)); // TypeError: s.indexOf is // not a function Bugs 11 / 41
  • 12.
    Bring back typechecking apply defensive techniques check against type function contains(c, s) { var index = typeof s === 'string' ? s.indexOf(c) : -1; return index > -1; } console.log(contains("hi", "there")); // false console.log(contains("hi", "hi!")); // true console.log(contains("hi", 1)); // false Bugs 12 / 41
  • 13.
    Figthing bugs inJS use a linter put runtime checks/assertions handle corner cases write more tests try to rule your growing codebase Bugs 13 / 41
  • 14.
    Isn't this ajob for a compiler? 14 / 41
  • 15.
    Catch'em at compiletime static type checking non-nullable types no implicit casts referential transparency Bugs 15 / 41
  • 16.
    How does Elmbehave? contains c s = (List.length (String.indexes c s)) > 0 v = contains "hi" 1 Bugs runnable example here 16 / 41
  • 17.
    Doesn't compile contains cs = (List.length (String.indexes c s)) > 0 v = contains "hi" 1 Bugs runnable example here 17 / 41
  • 18.
  • 19.
    What is Elm functionallanguage declarative UI design ML-like syntax immutable data structures statically and strongly typed Elm 19 / 41
  • 20.
    Strong typing if 0then doStuff else differentStuff Elm 20 / 41
  • 21.
    Immutable data structures a= 2 a = a + 3 Elm 21 / 41
  • 22.
    Functional first-class functions all functionscan be partially applied contains c s = (List.length (String.indexes c s)) > 0 containsH = contains "h" -- a new function all functions always return Elm 22 / 41
  • 23.
    Features compiles to Javascript followsElm Architecture inference engine enforces semantic versioning Javascript interoperability Elm 23 / 41
  • 24.
  • 25.
    The pattern model: thestate update: modify your state view: show your state Elm architecture 25 / 41
  • 26.
    The pattern model: thestate update: modify your state view: show your state update changes model using messages Elm architecture 26 / 41
  • 27.
    The counter! main = beginnerProgram{ model = 0, view = view, update = update } type Msg = Increment | Decrement update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 view model = div [] [ button [ onClick Decrement ] [ text "-" ] , div [] [ text (toString model) ] , button [ onClick Increment ] [ text "+" ] ] A trivial example try it live! 27 / 41
  • 28.
    Looks like Redux Elmarchitecture actually, Redux has been inspired by the Elm architecture... 28 / 41
  • 29.
    Looks like Redux itis part of the language no plugins, libraries, hacks just one way to go Elm architecture actually, Redux has been inspired by the Elm architecture... 29 / 41
  • 30.
    The virtual DOM evaluatewhat changes render what is needed lazy evaluation Performances 30 / 41
  • 31.
    JS output use arraysinstead of dictionaries references instead of looking up fully initialize objects hooks to requestAnimationFrame to save work Performances 31 / 41
  • 32.
    How does itcompare to competitors? 32 / 41
  • 33.
  • 34.
    Sorry, I lied Youcan still get runtime exceptions 34 / 41
  • 35.
    Sorry, I lied Youcan still get runtime exceptions If you use Javascript. 35 / 41
  • 36.
    Manual bootstrap var mountNode= document.getElementById('main'); var myApp = Elm.Main.embed(mountNode); can act on a subset of the page allows for slow integration can build a small module Javascript interoperability 36 / 41
  • 37.
    Ports get data fromJS code send data to JS code typed ports runtime assertions Javascript interoperability 37 / 41
  • 38.
    Inbound ports define theport type alias Move = (Float, Float) port scroll : (Move -> msg) -> Sub msg send data from JS code myApp.ports.scroll.send([scroll, newScroll]); Javascript interoperability code from MaltaJS Elm app 38 / 41
  • 39.
    Outbound ports define theport port todoListChanges : (List TodoItem) -> Cmd msg listen for data myApp.ports.todoListChanges.subscribe((updatedTodoList) => { /*...*/ }) Javascript interoperability code from TodoMVC done in Elm 39 / 41
  • 40.
    Elm Package Manager forcesdocumentation with a precise format must document every public item automatic semantic versioning Package system 40 / 41
  • 41.
    References: Elm website Elm slackcommunity Elm architecture Move fast and don't break things Thank you! 41 / 41