SlideShare a Scribd company logo
Rethinking Front
End Development
With Elm
Brian Hogan
About me
• I build web things.
• I teach people.
• I make music.
• I write books.
Elm is a functional programming language like Haskell, but more
friendly, and aimed at front-end web development.
We use Elm to make our user interface and give it behavior.
Example
import Graphics.Element exposing (show)
main =
show "Hello World"
Elm compiles to JavaScript
Yes. We just wrote a bunch of code that gets injected into an HTML
page.
Feel gross yet?
That's what React does too.
var HelloMessage = React.createClass({
render: function () {
return <h1>Hello {this.props.message}!</h1>;
}
});
React.render(<HelloMessage message="World" />, document.body);
Okay, Why Elm?
• Same concepts as React
• Pure functions
• Immutable State
• Static Typing
What you need
• Node.js http://nodejs.org
• The elm package for Node
$ npm install -g elm
• Your favorite text editor
OR
http://elm-lang.org/try
Compiling Elm
• Create a hello.elm file
• Run
$ elm make hello.elm
Success! Compiled 1 modules.
Successfully generated index.html
• Open resulting index.html in your browser.
HTML
Comparison
• Elm: ~5400 lines
• React: ~19300 lines
• JQuery: ~9800 lines
Elm Reactor
Elm Reactor compiles Elm to HTML on
each request.
$ elm-reactor
elm reactor 0.16.0
Listening on http://0.0.0.0:8000/
How Elm Works
Every Elm app calls a main function when we run it.
main =
-- something goes here
Functions
We define functions with a name followed by an = sign.
hello =
"Hello there"
We indent the definitions of functions.
We invoke this function like this:
hello
Arguments
Functions can have arguments
square number =
number * number
Call it as
square 2
They have explicit returns.
Multiple Arguments
Multiple arguments use spaces:
add number1 number2 =
number1 + number2
Call it as
add 1 2
Woah.... no commas!
Type annotations
We can enforce data types for our functions so Elm can help us out.
functionName: TypeOfArg1-> TypeOfArg2 -> TypeOfArg3 -> ReturnType
Annotation Examples:
No parameters. Just return value
hello: String
hello =
"Hello there"
Two parameters and a return value
add: Float -> Float -> Float
add number1 number2 =
number1 + number2
Modules
Define modules to group your code.
module Hello where
main =
-- something goes here
Html functions
The elm-html module exposes many functions for building up virtual
DOM nodes.
The main function can render HTML if the HTML module is included.
import Html exposing(p, text)
main =
p [] [text "Hello World"]
p and text
p [] [text "Hello World"]
p and text are two functions from elm-html
p takes two lists
• a list of attributes (can be empty)
• a list of child elements
text takes a string of text to display.
HTML functions are uniform.
Each takes attributes and elements. So we can nest them like HTML.
div [class "foo", id "bar" ] [
h1 [] [text "Hello"],
p [] [text "World"]
]
There's a function for every element. Just be sure to expose what you
use.
Seriously uniform
label [for "name"] [text "Name"]
input [id "name", type' "number", step "any"] []
Even functions for tags that don't allow inner content still take two
lists as arguments.
Html Modules
• Html contains all the tags
• Html.Attributes contains the attributes (like class, id, href,
etc)
• Html.Events contains events like onClick
Html Attributes
import Html exposing(Html, div, text, p)
import Html.Attributes exposing(class)
main =
div [class "wrapper"] [
p [class "notice"] [text "This is important!"]
]
Composability
main =
view
view: Html
view =
div [] [
p [] [
text "Hello ",
em [] [text "world"]
]
]
Resuability
main =
div [] [
view "Hello",
view "Goodbye"
]
view: String -> Html
view word =
div [] [
p [] [ text (word ++ " "), em [] [text "world"] ]
]
Web Interfaces
import Html exposing(Html, Attribute, p, text)
import Html.Attributes exposing(style)
elementStyle: Attribute
elementStyle =
style [ ("color", "red") , ("font-size", "2em") ]
main: Html
main =
view
view =
p [elementStyle] [text "Hello World"]
Helpers!
fieldWithLabel: String -> String -> String -> Html
fieldWithLabel fieldID fieldName fieldType =
div [] [
label [for fieldID] [text fieldName],
input [ id fieldID, type' fieldType] []
]
Build Out The Helpers
numberField: String -> String -> Html
numberField fieldID fieldName =
fieldWithLabel fieldID fieldName "number"
textField: String -> String -> Html
textField fieldID fieldName =
fieldWithLabel fieldID fieldName "text"
emailField: String -> String -> Html
emailField fieldID fieldName =
fieldWithLabel fieldID fieldName "email"
Shiny Happy Frontend Code
main: Html
main =
div [] [
textField "name" "Name",
numberField "age" "Age",
emailField "email" "Email"
]
Elm Architecture
View: Function that fires when model changes. Transofms a model
into the UI that people see.
Model: Something that holds the current state of the app. No behavior.
Just the state. No behavior. This is not MVC with objects!
Update: Function that fires when state changes. Always returns a new
model.
Signals and Mailboxes
Signals
Signals route messages around the application. Pressing a button is a
signal. We can send data along signals.
Mailboxes
Mailboxes receive signals and send signals. A mailbox has an address
and a signal to respond to.
Basic Flow
• Model is initialized
• View is displayed with model
• Events send Signals to Mailboxes
• Mailboxes trigger updates
• New model is created
• New view is rendered
Yikes!
Elm StartApp.Simple
Like Flux, without all the code.
• Define Actions
• Define a model to represent data
• Define a view function
• Define an update function that returns a new model.
Change Text On Click
import Html exposing (Html, text, h1, p, div, button)
import StartApp.Simple as StartApp
import Html.Events exposing (onClick)
main =
StartApp.start {model = "Hello ", view = view, update = update}
view address initialText =
div [] [
h1 [] [text "Events"],
p [] [ text initialText ],
button [onClick address "change"] [text "Push me"]
]
update action model =
"it changed"
Actions
Actions get sent to the Update.
type Action = Increment | Decrement
model = 0
update: Signal.Action -> Int -> Int
update action model =
case action of
Increment -> model + 1
Decrement -> model - 1
Multiple events
main =
StartApp.start { model = model, view = view, update = update }
view: Signal.Address Action -> Int -> Html
view address model =
div []
[ button [ onClick address Increment ] [ text "Up" ]
, span [] [ text (toString model) ]
, button [ onClick address Decrement ] [ text "Down" ]
]
Once again...
• StartApp renders the view using an initial model state.
• Events defined in the view send Actions to Signal Addresses
which route to update.
• update returns a new version of the model
• StartApp causes the view to be rendered whenever model
changes.
Calculator
Compound Interest Calculator
Write a program to compute the value of an investment compounded
over time. The program should ask for the starting amount, the
number of years to invest, the interest rate, and the number of periods
per year to compound.
Project setup
Create folder and file to work in
$ mkdir calculator && cd calculator
$ touch calculator.elm
Init the project
$ elm package install
Install HTML and StartApp dependencies.
$ elm package install evancz/elm-html
$ elm package install evancz/start-app
Livereloading
Make browser reload when we save
$ npm install -g elm-live
$ elm-live calculator.elm
Steps
• Create the basic app
• Build the form
• Bind form to model and define events
• Perform calculations
• Display Output
The Basic App
import Html exposing (Html, text, h1, p, div, button, label, input)
import Html.Attributes exposing ( style, for, id, step, type', value)
import StartApp.Simple as StartApp
import Html.Events exposing (onClick)
main =
StartApp.start {model = model, view = view, update = update}
Define a model and update
model: Float
model = 0
update: String -> Float -> Float
update action model =
model
Building the form
• Use label, input functions
• Use number fields
• Each field change updates model state
• Clicking button calculates new amount
numberField helper
numberField: String -> String -> Html
numberField fieldID fieldName =
div [] [
label [for fieldID] [text fieldName],
input [ id fieldID, type' "number", step "any"] []
]
Style the form
labelStyle: Attribute
labelStyle =
style
[ ("width", "200px")
, ("padding", "10px")
, ("text-align", "right")
, ("display", "inline-block")
]
Apply style to field
div [] [
label [labelStyle, for fieldID] [text fieldName],
input [ id fieldID, type' "number", step "any"] []
]
Build the View
view: Signal.Address String -> Float -> Html
view address model =
div [] [
h1 [] [text "Calculator"],
div [] [
numberField "principal" "Principal",
numberField "rate" "Rate",
numberField "years" "Periods",
numberField "years" "Years"
]
button [onClick address "calculate"] [text "Calculate"]
]
Define Our Actions
type Action
= NoOp
| SetPrinciple String
| SetPeriods String
| SetRate String
| SetYears String
| Calculate
Define A Model
type alias Model =
{ principle: String
, rate: String
, years: String
, periods: String
, newAmount: Float}
model: Model
model =
{ principle = "1500.00"
, rate = "4.3"
, years = "6"
, periods = "4"
, newAmount = 0 }
Pass address, action, and model data to fields
view: Signal.Address Action -> Model -> Html
view address model =
div [] [
h1 [] [text "Calculator"],
div [] [
numberField address SetPrinciple "principle" "Principle" model.principle,
numberField address SetRate "rate" "Rate" model.rate,
numberField address SetPeriods "periods" "Periods" model.periods,
numberField address SetYears "years" "Years" model.years
],
button [onClick address Calculate] [text "Click me"],
Add Events To Form using Actions and model data
numberField: Signal.Address Action -> (String -> Action) ->
String -> String -> String -> Html
numberField address action fieldID name fieldValue =
div [] [
label [labelStyle, for fieldID] [text name],
input [id fieldID, type' "number", step "any",
on "input" targetValue (Signal.message address << action ),
value fieldValue] []
]
Update model from form
update: Action -> Model -> Model
update action model =
case action of
NoOp -> model
SetPrinciple p -> {model | principle = p}
SetRate r -> {model | rate = r}
SetYears y -> {model | years = y}
SetPeriods p -> {model | periods = p}
Calculate -> calculateNewAmount model
The program Logic
compoundInterest: Float -> Float -> Float -> Float -> Float
compoundInterest principle rate periods years =
(principle * (1 + (rate / periods ) ) ^ (years * periods) )
Converting Strings To Floats
convertToFloat: String -> Float
convertToFloat string =
case String.toFloat string of
Ok n -> n
Err _ -> 0.0
Implement CalculateNewAmount
calculateNewAmount: Model -> Model
calculateNewAmount model =
let
rate = convertToFloat model.rate / 100
years = convertToFloat model.years
principle = convertToFloat model.principle
periods = convertToFloat model.periods
in
{model | newAmount = (compoundInterest principle rate periods years) }
Display the Output
output: Model -> Html
output model =
div [] [
span [] [text "Amount: "],
span [] [text (toString model.newAmount) ]
]
And add it to the view.
Discuss
What are your thoughts?
Is this cool? Good? Bad? A terrible idea or
the greatest thing ever?
Issues
1. Tons of code to do simple things
2. Integration with external services is
complex
3. Must re-learn a lot of things about web
development
4. Small community
Benefits
1. Small community
2. Benefits of React with a clear
opinionated approach
3. Fantastic error messages
4. Types ensure data integrity and flow
Write code
• Elm website: http://elm-lang.org/
• Try Elm http://elm-lang.org/try
• Package system: http://package.elm-
lang.org/
• Documentation http://elm-lang.org/docs
Where to go next?
Book: http://pragprog.com/titles/bhwb
Twitter: @bphogan
Material: http://bphogan.com/
presentations/elm2016/
Thank you!
© Brian Hogan, 2016.
Photos from http://pexels.com

More Related Content

PDF
Rethink Frontend Development With Elm
PPT
Html JavaScript and CSS
PDF
Print function in PHP
PPT
Dynamic HTML Event Model
PDF
Client side scripting
PPTX
Form Validation in JavaScript
PDF
phptut2
Rethink Frontend Development With Elm
Html JavaScript and CSS
Print function in PHP
Dynamic HTML Event Model
Client side scripting
Form Validation in JavaScript
phptut2

What's hot (17)

PPTX
Javascript
PPT
A quick guide to Css and java script
PDF
WPF L02-Graphics, Binding and Animation
ODP
HTML 5 Simple Tutorial Part 4
PPT
1. introduction to html5
PDF
Java script
PPTX
Javascript
PDF
WPF L01-Layouts, Controls, Styles and Templates
PPT
Java Script ppt
PPTX
Java script
PDF
Students Stars
PPTX
Web programming
ZIP
Fundamental JavaScript [In Control 2009]
PPTX
Java script
PPT
JavaScript Workshop
PPT
Learn javascript easy steps
DOC
Html basics 10 form
 
Javascript
A quick guide to Css and java script
WPF L02-Graphics, Binding and Animation
HTML 5 Simple Tutorial Part 4
1. introduction to html5
Java script
Javascript
WPF L01-Layouts, Controls, Styles and Templates
Java Script ppt
Java script
Students Stars
Web programming
Fundamental JavaScript [In Control 2009]
Java script
JavaScript Workshop
Learn javascript easy steps
Html basics 10 form
 
Ad

Viewers also liked (20)

PDF
Introduction to Elm
PDF
My adventure with Elm
PDF
Elm a possible future for web frontend
PDF
Claudia Doppioslash - Time Travel for game development with Elm
PDF
Elm: frontend code without runtime exceptions
ODP
Very basic functional design patterns
ODP
Elixir and elm - the perfect couple
PDF
Unic - frontend development-in-complex-projects
PPTX
Technology independent UI development with JVx
PDF
Elm: delightful web development
PDF
Web Frontend development: tools and good practices to (re)organize the chaos
PDF
Agile IT: Modern Architecture for Rapid Mobile App Development
PDF
Basics of Rich Internet Applications
PDF
Collaborative music with elm and phoenix
PDF
Functional Web Development using Elm
PDF
Nodejs - A quick tour (v6)
PPTX
Comparison of Java Web Application Frameworks
PDF
React redux
PPT
Modern Rapid Application Development - Too good to be true
PDF
Need for Async: Hot pursuit for scalable applications
Introduction to Elm
My adventure with Elm
Elm a possible future for web frontend
Claudia Doppioslash - Time Travel for game development with Elm
Elm: frontend code without runtime exceptions
Very basic functional design patterns
Elixir and elm - the perfect couple
Unic - frontend development-in-complex-projects
Technology independent UI development with JVx
Elm: delightful web development
Web Frontend development: tools and good practices to (re)organize the chaos
Agile IT: Modern Architecture for Rapid Mobile App Development
Basics of Rich Internet Applications
Collaborative music with elm and phoenix
Functional Web Development using Elm
Nodejs - A quick tour (v6)
Comparison of Java Web Application Frameworks
React redux
Modern Rapid Application Development - Too good to be true
Need for Async: Hot pursuit for scalable applications
Ad

Similar to Rethink Frontend Development With Elm (20)

PDF
Elm 0.17 at Dublin Elm Meetup May 2016
PDF
Html css
PDF
JavaScript - Chapter 12 - Document Object Model
PPT
Scripting languages
PPTX
Javascript
PPTX
unit4 wp.pptxjvlbpuvghuigv8ytg2ugvugvuygv
PDF
Android L01 - Warm Up
PPTX
dotnetConf2019 meetup in AICHI / Elmish
PDF
Html5ppt
PDF
A proper introduction to Elm
PPTX
Python Code Camp for Professionals 4/4
PPTX
HTML5 - Quick Guide
PDF
Elm @ DublinJS
PDF
What About Elm?
PPTX
Introduction to java script, how to include java in HTML
PPTX
WEB DEVELOPMENT
PDF
Visualbasic tutorial
PDF
Build a game with javascript (april 2017)
PPTX
Code camp 2011 Getting Started with IOS, Una Daly
PDF
Introduzione JQuery
Elm 0.17 at Dublin Elm Meetup May 2016
Html css
JavaScript - Chapter 12 - Document Object Model
Scripting languages
Javascript
unit4 wp.pptxjvlbpuvghuigv8ytg2ugvugvuygv
Android L01 - Warm Up
dotnetConf2019 meetup in AICHI / Elmish
Html5ppt
A proper introduction to Elm
Python Code Camp for Professionals 4/4
HTML5 - Quick Guide
Elm @ DublinJS
What About Elm?
Introduction to java script, how to include java in HTML
WEB DEVELOPMENT
Visualbasic tutorial
Build a game with javascript (april 2017)
Code camp 2011 Getting Started with IOS, Una Daly
Introduzione JQuery

More from Brian Hogan (20)

PDF
Creating and Deploying Static Sites with Hugo
PDF
Automating the Cloud with Terraform, and Ansible
PDF
Create Development and Production Environments with Vagrant
PDF
Docker
PDF
Getting Started Contributing To Open Source
KEY
Testing Client-side Code with Jasmine and CoffeeScript
KEY
FUD-Free Accessibility for Web Developers - Also, Cake.
KEY
Responsive Web Design
KEY
Web Development with CoffeeScript and Sass
KEY
Building A Gem From Scratch
KEY
Intro To Advanced Ruby
KEY
Turning Passion Into Words
PDF
HTML5 and CSS3 Today
PDF
Web Development With Ruby - From Simple To Complex
KEY
Stop Reinventing The Wheel - The Ruby Standard Library
KEY
Intro to Ruby
KEY
Intro to Ruby - Twin Cities Code Camp 7
KEY
Make GUI Apps with Shoes
KEY
The Why Of Ruby
KEY
Story-driven Testing
Creating and Deploying Static Sites with Hugo
Automating the Cloud with Terraform, and Ansible
Create Development and Production Environments with Vagrant
Docker
Getting Started Contributing To Open Source
Testing Client-side Code with Jasmine and CoffeeScript
FUD-Free Accessibility for Web Developers - Also, Cake.
Responsive Web Design
Web Development with CoffeeScript and Sass
Building A Gem From Scratch
Intro To Advanced Ruby
Turning Passion Into Words
HTML5 and CSS3 Today
Web Development With Ruby - From Simple To Complex
Stop Reinventing The Wheel - The Ruby Standard Library
Intro to Ruby
Intro to Ruby - Twin Cities Code Camp 7
Make GUI Apps with Shoes
The Why Of Ruby
Story-driven Testing

Recently uploaded (20)

PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
System and Network Administration Chapter 2
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PPTX
Transform Your Business with a Software ERP System
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
medical staffing services at VALiNTRY
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Operating system designcfffgfgggggggvggggggggg
wealthsignaloriginal-com-DS-text-... (1).pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Odoo Companies in India – Driving Business Transformation.pdf
System and Network Administration Chapter 2
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Transform Your Business with a Software ERP System
Design an Analysis of Algorithms I-SECS-1021-03
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Which alternative to Crystal Reports is best for small or large businesses.pdf
2025 Textile ERP Trends: SAP, Odoo & Oracle
medical staffing services at VALiNTRY
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Reimagine Home Health with the Power of Agentic AI​
VVF-Customer-Presentation2025-Ver1.9.pptx
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)

Rethink Frontend Development With Elm

  • 2. About me • I build web things. • I teach people. • I make music. • I write books.
  • 3. Elm is a functional programming language like Haskell, but more friendly, and aimed at front-end web development. We use Elm to make our user interface and give it behavior.
  • 4. Example import Graphics.Element exposing (show) main = show "Hello World"
  • 5. Elm compiles to JavaScript Yes. We just wrote a bunch of code that gets injected into an HTML page. Feel gross yet?
  • 6. That's what React does too. var HelloMessage = React.createClass({ render: function () { return <h1>Hello {this.props.message}!</h1>; } }); React.render(<HelloMessage message="World" />, document.body);
  • 7. Okay, Why Elm? • Same concepts as React • Pure functions • Immutable State • Static Typing
  • 8. What you need • Node.js http://nodejs.org • The elm package for Node $ npm install -g elm • Your favorite text editor OR http://elm-lang.org/try
  • 9. Compiling Elm • Create a hello.elm file • Run $ elm make hello.elm Success! Compiled 1 modules. Successfully generated index.html • Open resulting index.html in your browser.
  • 10. HTML
  • 11. Comparison • Elm: ~5400 lines • React: ~19300 lines • JQuery: ~9800 lines
  • 12. Elm Reactor Elm Reactor compiles Elm to HTML on each request. $ elm-reactor elm reactor 0.16.0 Listening on http://0.0.0.0:8000/
  • 13. How Elm Works Every Elm app calls a main function when we run it. main = -- something goes here
  • 14. Functions We define functions with a name followed by an = sign. hello = "Hello there" We indent the definitions of functions. We invoke this function like this: hello
  • 15. Arguments Functions can have arguments square number = number * number Call it as square 2 They have explicit returns.
  • 16. Multiple Arguments Multiple arguments use spaces: add number1 number2 = number1 + number2 Call it as add 1 2 Woah.... no commas!
  • 17. Type annotations We can enforce data types for our functions so Elm can help us out. functionName: TypeOfArg1-> TypeOfArg2 -> TypeOfArg3 -> ReturnType
  • 18. Annotation Examples: No parameters. Just return value hello: String hello = "Hello there" Two parameters and a return value add: Float -> Float -> Float add number1 number2 = number1 + number2
  • 19. Modules Define modules to group your code. module Hello where main = -- something goes here
  • 20. Html functions The elm-html module exposes many functions for building up virtual DOM nodes. The main function can render HTML if the HTML module is included. import Html exposing(p, text) main = p [] [text "Hello World"]
  • 21. p and text p [] [text "Hello World"] p and text are two functions from elm-html p takes two lists • a list of attributes (can be empty) • a list of child elements text takes a string of text to display.
  • 22. HTML functions are uniform. Each takes attributes and elements. So we can nest them like HTML. div [class "foo", id "bar" ] [ h1 [] [text "Hello"], p [] [text "World"] ] There's a function for every element. Just be sure to expose what you use.
  • 23. Seriously uniform label [for "name"] [text "Name"] input [id "name", type' "number", step "any"] [] Even functions for tags that don't allow inner content still take two lists as arguments.
  • 24. Html Modules • Html contains all the tags • Html.Attributes contains the attributes (like class, id, href, etc) • Html.Events contains events like onClick
  • 25. Html Attributes import Html exposing(Html, div, text, p) import Html.Attributes exposing(class) main = div [class "wrapper"] [ p [class "notice"] [text "This is important!"] ]
  • 26. Composability main = view view: Html view = div [] [ p [] [ text "Hello ", em [] [text "world"] ] ]
  • 27. Resuability main = div [] [ view "Hello", view "Goodbye" ] view: String -> Html view word = div [] [ p [] [ text (word ++ " "), em [] [text "world"] ] ]
  • 28. Web Interfaces import Html exposing(Html, Attribute, p, text) import Html.Attributes exposing(style) elementStyle: Attribute elementStyle = style [ ("color", "red") , ("font-size", "2em") ] main: Html main = view view = p [elementStyle] [text "Hello World"]
  • 29. Helpers! fieldWithLabel: String -> String -> String -> Html fieldWithLabel fieldID fieldName fieldType = div [] [ label [for fieldID] [text fieldName], input [ id fieldID, type' fieldType] [] ]
  • 30. Build Out The Helpers numberField: String -> String -> Html numberField fieldID fieldName = fieldWithLabel fieldID fieldName "number" textField: String -> String -> Html textField fieldID fieldName = fieldWithLabel fieldID fieldName "text" emailField: String -> String -> Html emailField fieldID fieldName = fieldWithLabel fieldID fieldName "email"
  • 31. Shiny Happy Frontend Code main: Html main = div [] [ textField "name" "Name", numberField "age" "Age", emailField "email" "Email" ]
  • 32. Elm Architecture View: Function that fires when model changes. Transofms a model into the UI that people see. Model: Something that holds the current state of the app. No behavior. Just the state. No behavior. This is not MVC with objects! Update: Function that fires when state changes. Always returns a new model.
  • 33. Signals and Mailboxes Signals Signals route messages around the application. Pressing a button is a signal. We can send data along signals. Mailboxes Mailboxes receive signals and send signals. A mailbox has an address and a signal to respond to.
  • 34. Basic Flow • Model is initialized • View is displayed with model • Events send Signals to Mailboxes • Mailboxes trigger updates • New model is created • New view is rendered Yikes!
  • 35. Elm StartApp.Simple Like Flux, without all the code. • Define Actions • Define a model to represent data • Define a view function • Define an update function that returns a new model.
  • 36. Change Text On Click import Html exposing (Html, text, h1, p, div, button) import StartApp.Simple as StartApp import Html.Events exposing (onClick) main = StartApp.start {model = "Hello ", view = view, update = update} view address initialText = div [] [ h1 [] [text "Events"], p [] [ text initialText ], button [onClick address "change"] [text "Push me"] ] update action model = "it changed"
  • 37. Actions Actions get sent to the Update. type Action = Increment | Decrement model = 0 update: Signal.Action -> Int -> Int update action model = case action of Increment -> model + 1 Decrement -> model - 1
  • 38. Multiple events main = StartApp.start { model = model, view = view, update = update } view: Signal.Address Action -> Int -> Html view address model = div [] [ button [ onClick address Increment ] [ text "Up" ] , span [] [ text (toString model) ] , button [ onClick address Decrement ] [ text "Down" ] ]
  • 39. Once again... • StartApp renders the view using an initial model state. • Events defined in the view send Actions to Signal Addresses which route to update. • update returns a new version of the model • StartApp causes the view to be rendered whenever model changes.
  • 40. Calculator Compound Interest Calculator Write a program to compute the value of an investment compounded over time. The program should ask for the starting amount, the number of years to invest, the interest rate, and the number of periods per year to compound.
  • 41. Project setup Create folder and file to work in $ mkdir calculator && cd calculator $ touch calculator.elm Init the project $ elm package install Install HTML and StartApp dependencies. $ elm package install evancz/elm-html $ elm package install evancz/start-app
  • 42. Livereloading Make browser reload when we save $ npm install -g elm-live $ elm-live calculator.elm
  • 43. Steps • Create the basic app • Build the form • Bind form to model and define events • Perform calculations • Display Output
  • 44. The Basic App import Html exposing (Html, text, h1, p, div, button, label, input) import Html.Attributes exposing ( style, for, id, step, type', value) import StartApp.Simple as StartApp import Html.Events exposing (onClick) main = StartApp.start {model = model, view = view, update = update}
  • 45. Define a model and update model: Float model = 0 update: String -> Float -> Float update action model = model
  • 46. Building the form • Use label, input functions • Use number fields • Each field change updates model state • Clicking button calculates new amount
  • 47. numberField helper numberField: String -> String -> Html numberField fieldID fieldName = div [] [ label [for fieldID] [text fieldName], input [ id fieldID, type' "number", step "any"] [] ]
  • 48. Style the form labelStyle: Attribute labelStyle = style [ ("width", "200px") , ("padding", "10px") , ("text-align", "right") , ("display", "inline-block") ]
  • 49. Apply style to field div [] [ label [labelStyle, for fieldID] [text fieldName], input [ id fieldID, type' "number", step "any"] [] ]
  • 50. Build the View view: Signal.Address String -> Float -> Html view address model = div [] [ h1 [] [text "Calculator"], div [] [ numberField "principal" "Principal", numberField "rate" "Rate", numberField "years" "Periods", numberField "years" "Years" ] button [onClick address "calculate"] [text "Calculate"] ]
  • 51. Define Our Actions type Action = NoOp | SetPrinciple String | SetPeriods String | SetRate String | SetYears String | Calculate
  • 52. Define A Model type alias Model = { principle: String , rate: String , years: String , periods: String , newAmount: Float} model: Model model = { principle = "1500.00" , rate = "4.3" , years = "6" , periods = "4" , newAmount = 0 }
  • 53. Pass address, action, and model data to fields view: Signal.Address Action -> Model -> Html view address model = div [] [ h1 [] [text "Calculator"], div [] [ numberField address SetPrinciple "principle" "Principle" model.principle, numberField address SetRate "rate" "Rate" model.rate, numberField address SetPeriods "periods" "Periods" model.periods, numberField address SetYears "years" "Years" model.years ], button [onClick address Calculate] [text "Click me"],
  • 54. Add Events To Form using Actions and model data numberField: Signal.Address Action -> (String -> Action) -> String -> String -> String -> Html numberField address action fieldID name fieldValue = div [] [ label [labelStyle, for fieldID] [text name], input [id fieldID, type' "number", step "any", on "input" targetValue (Signal.message address << action ), value fieldValue] [] ]
  • 55. Update model from form update: Action -> Model -> Model update action model = case action of NoOp -> model SetPrinciple p -> {model | principle = p} SetRate r -> {model | rate = r} SetYears y -> {model | years = y} SetPeriods p -> {model | periods = p} Calculate -> calculateNewAmount model
  • 56. The program Logic compoundInterest: Float -> Float -> Float -> Float -> Float compoundInterest principle rate periods years = (principle * (1 + (rate / periods ) ) ^ (years * periods) )
  • 57. Converting Strings To Floats convertToFloat: String -> Float convertToFloat string = case String.toFloat string of Ok n -> n Err _ -> 0.0
  • 58. Implement CalculateNewAmount calculateNewAmount: Model -> Model calculateNewAmount model = let rate = convertToFloat model.rate / 100 years = convertToFloat model.years principle = convertToFloat model.principle periods = convertToFloat model.periods in {model | newAmount = (compoundInterest principle rate periods years) }
  • 59. Display the Output output: Model -> Html output model = div [] [ span [] [text "Amount: "], span [] [text (toString model.newAmount) ] ] And add it to the view.
  • 60. Discuss What are your thoughts? Is this cool? Good? Bad? A terrible idea or the greatest thing ever?
  • 61. Issues 1. Tons of code to do simple things 2. Integration with external services is complex 3. Must re-learn a lot of things about web development 4. Small community
  • 62. Benefits 1. Small community 2. Benefits of React with a clear opinionated approach 3. Fantastic error messages 4. Types ensure data integrity and flow
  • 63. Write code • Elm website: http://elm-lang.org/ • Try Elm http://elm-lang.org/try • Package system: http://package.elm- lang.org/ • Documentation http://elm-lang.org/docs
  • 64. Where to go next? Book: http://pragprog.com/titles/bhwb Twitter: @bphogan Material: http://bphogan.com/ presentations/elm2016/ Thank you! © Brian Hogan, 2016. Photos from http://pexels.com