by Daniel Bachler (@danyx23)
this presentation is available at:
slides.com/danielbachler/fearless-refactoring-with-elm
the language
the architecture
the infrastructure
my experience so far
function addNumbers(a, b) {
return a + b;
}
// Whatever
addNumbers(4, "three");
addNumbers a b =
a + b
-- Types are infered to be numbers
-- This is a compile time error
addNumbers 4 "three"
-- Union Type
type Gender
= Male
| Female
| Other String
personAGender = Male
personBGender = Other "Androgynous"
printGender gender =
case gender of
Male ->
"male"
Female ->
"female"
Other selfdefined ->
selfdefined
-- There is no null, no undefined
type alias Person =
{ firstName : String
, lastName : String
, yearOfBirth : Int
}
-- not possible
personA = { firstName = "Lao"
, lastName = "Tse"
, yearOfBirth = null
}
birthYearToString person =
toString person.yearOfBirth
-- instead:
type alias Person =
{ firstName : String
, lastName : String
, yearOfBirth : Maybe Int
}
personA = { firstName = "Lao"
, lastName = "Tse"
, yearOfBirth = Nothing
}
birthYearToString person =
case person.yearOfBirth of
Nothing ->
"Unknown"
Just age ->
toString age
x = 1
x = 2 -- compile error
x = x + 1 -- compile error
y = x + 1 -- ok
addNumbers : Int -> Int -> Int
addNumbers a b =
a + b
birthYearToString : Person -> String
birthYearToString person =
...
addNumbers : Int -> Int -> Int
addNumbers a b =
a + b
result1 = addNumbers 1 2
result2 = addNumbers 1 2
result 1 == result 2 -- True
Calling the same function again with the same arguments will always return the same value, never have any side effects
function addNumbersWeird(a, b) {
window.myGlobalState = window.myGlobalState || 0;
return a + b + (window.myGlobalState++);
}
var result1 = addNumbersWeird(1, 2);
var result2 = addNumbersWeird(1, 2);
result1 == result2; // False
Very similar to React without local state + Redux
Diagram by Evan Czaplicki
See also André Staltz' great overview of unidirectional UI aproaches
-- MODEL
type alias Model = Int
-- UPDATE
type Action = Increment | Decrement
update : Action -> Model -> Model
update action model =
case action of
Increment ->
model + 1
Decrement ->
model - 1
-- VIEW
view : Signal.Address Action -> Model -> Html
view address model =
div []
[ button [ onClick address Decrement ] [ text "-" ]
, div [ countStyle ] [ text (toString model) ]
, button [ onClick address Increment ] [ text "+" ]
]
countStyle : Attribute
countStyle =
style
[ ("font-size", "20px")
, ("font-family", "monospace")
, ("display", "inline-block")
, ("width", "50px")
, ("text-align", "center")
]
-- Wire everything together
main =
start
{ model = 0
, update = update
, view = view
}
elm make
elm repl
elm package
Should we do a hackathon style
meetup in Berlin?
by Daniel Bachler (@danyx23 on twitter)