%title: Functional Programming with Elm %author: @_andys8 - jambit.com %date: 2019
┏━╸╻ ╻┏┓╻┏━╸╺┳╸╻┏━┓┏┓╻┏━┓╻ ┣╸ ┃ ┃┃┗┫┃ ┃ ┃┃ ┃┃┗┫┣━┫┃ ╹ ┗━┛╹ ╹┗━╸ ╹ ╹┗━┛╹ ╹╹ ╹┗━╸ ┏━┓┏━┓┏━┓┏━╸┏━┓┏━┓┏┳┓┏┳┓╻┏┓╻┏━╸ ┣━┛┣┳┛┃ ┃┃╺┓┣┳┛┣━┫┃┃┃┃┃┃┃┃┗┫┃╺┓ ╹ ╹┗╸┗━┛┗━┛╹┗╸╹ ╹╹ ╹╹ ╹╹╹ ╹┗━┛ ╻┏┓╻ ┏━╸╻ ┏┳┓ ┃┃┗┫ ┣╸ ┃ ┃┃┃ ╹╹ ╹ ┗━╸┗━╸╹ ╹
- Elm
- Purpose
- Features
- JavaScript to Elm
- Syntax
- Functions
- Types
- Getting started
- The Elm Architecture
- Ellie
- create-elm-app
- Demo and code
- Vim in Elm
- Customer project
.://+ooosoo++/:-`
`:+ssssssoooooossssss+:.
.+sssso/-.`` `.-/+ossso:`
.+ssso:. ``` `:+ssso-
:ssso:` `.:+osyyys: .+sss+`
/sss+` `:oyhhhhhhhhy. :ssso`
:sss+` .+yhhhhhhhhhho..-/+: -sss+
`osso` `/yhhhhhhhhhhs:/shhhhs /sss-
-sss/ `shhhhhhhhhys+shhhhhhh+ -sss/
-sss: shhhhhhhhyooyhhhhhhhhy` .sss+
.sss/ :hhhhhhyo+syhhhhhhhhhs. -sss/
osso` +hhhyo/:ohhhhhhhhhhy/` +sss.
-sss+` `::.``+hhhhhhhhhhy+. :sss/
:sss+. `shhhhhhhhs+-` `/sss+`
-osso/. .+oooo+/-.` `:osss/`
`/ssso/-` ./osss+.
./ossso+:-..`````.-:+ossss/.
`./osssssssoossssssso/-`
`.-:/++++++//:.`
For reliable webapps
Generate JavaScript with
great performance and no runtime exceptions.
- PureScript
- TypeScript
- ClojureScript
- ReasonML
A pure functional language Functions have no side effects Focus on simplicity Everything is immutable
Small ecosystem Learning curve How will we hire people?
Fewer rendering bugs More maintainable code Growing as developers
From Rails to Elm and Haskell by Richard Feldman
Data in, data out
\ Input +--------------+ Output \ +---------->+ Function +----------> \ +--------------+
- No side effects
- Referential transparency
- Testable
Errors at compile time
"If it compiles, it works"
This `user` record does not have a `naame` field:
17| myUser = user.naame
^^^^^
This is usually a typo.
Here are the `user` fields that are most similar:
{ name : String
}
So maybe naame should be name?
- 100kb Vue 2.5
- 93kb Angular 6
- 77kb React 16.4
- 29kb Elm 0.19
Under 2 seconds for 50k lines of code From scratch
Function-level dead code elimination.
Possible because:
- Elm functions cannot be redefined or removed at runtime.
- Every package is written entirely in Elm
const name = "my-name";
function add(x, y) {
return x + y;
}
const result = add(1, 2);
^
name = "my-name"
add x y = x + y
result = add 1 2
name : String
name =
"my-name"
add : Int -> Int -> Int
add x y =
x + y
result : Int
result =
add 1 2
Let's learn more Elm syntax
====================== = It's ML syntax = ======================
Used in Haskell, Standard ML, OCaml, PureScript, or F#
type alias Point = { x:Float, y:Float }
origin : Point
origin =
{ x = 0, y = 0 }
type Color = Red | Yellow | Green
^
type User
= Regular String Int
| Visitor String
type Maybe a
= Just a
| Nothing
There is no null
Elm is telling the truth
String.toInt : String -> Maybe Int
TypeScript and Java are hiding NaN
/ NumberFormatException
declare function parseInt(s:string):number;
static int parseInt(String s)
type RemoteData e a
= NotAsked
| Loading
| Failure e
| Success a
^ NotAsked We haven't asked for the data yet.
Loading We've asked, but haven't got an answer yet.
Failure We asked, but something went wrong.
Success Everything worked, and here's the data.
viewNames : List String -> String
viewNames names =
String.join ", " (List.sort names)
^
viewNames names =
names
|> List.sort
|> String.join ", "
^
viewNames =
List.sort >> String.join ", "
- The Elm Architecture
- Ellie
- Create-Elm-App
An Elm program contains:
- Model
- Update
- View
Model Message
+-------------+
+----->+ View +-----+
| +-------------+ |
| |
| |
| v
+-+--------------------------+-+
| Elm Runtime |
+-+--------------------------+-+
^ |
| |
| |
| +-------------+ |
+------+ Update +<----+
+-------------+
New Model Prev. Model
+ Side-Effects + Message
type alias Model =
{ count : Int }
initialModel : Model
initialModel =
{ count = 0 }
type Msg
= Increment
| Decrement
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
{ model | count = model.count + 1 }
Decrement ->
{ model | count = model.count - 1 }
view : Model -> Html Msg
view model =
div []
[ div [] [ text <| String.fromInt model.count ]
, button [ onClick Decrement ] [ text "-1" ]
, button [ onClick Increment ] [ text "+1" ]
]
main : Program () Model Msg
main =
Browser.sandbox
{ init = initialModel
, view = view
, update = update
}
Possible Changes:
- Add Reset button
- Add Msg
ChangeWith (Int -> Int)
- Refactor buttons to use ChangeWith
- Add Double button
- No build configuration
- Like
create-react-app
- Webpack based
- Hot module reloading
- Assets, CSS, and JS
- Tests
Vim is a highly configurable text editor for efficiently creating and changing any kind of text.
Vim is known for HJKL keybindings
Elm chat-engine application for a customer
- Language features and benefits
- JavaScript to Elm
- The Elm Architecture
- Tools like Ellie or create-elm-app
- Demo time with Vim in Elm
Guides, Talks and Workshops
- Elm Guide
- Sporto Elm Workshop
- Feldman Workshop
- Toward a Better Front End Architecture
- Richard Feldman - Scaling Elm Apps
- Life of a file
“If only I had a job writing <Haskell|purescript|Elm|X>”
STOP!
If you ❤️ that language start teaching it. Get people involved. Own it!
Try out Elm.
- Find a low-risk project that's a good fit
- Get it into production
- Expand incrementally or back out