Scenic City Summit 2017: Tame the frontend with Elm

Scenic City Summit 2017: Tame the frontend with Elm

94bd558238b69c45d3d3e15797ae94f7?s=128

Jeremy Fairbank

July 28, 2017
Tweet

Transcript

  1. 5.
  2. 7.

    elm

  3. 10.
  4. 12.

    elm

  5. 14.

    greet name = "Hello, " ++ name greet "Scenic City

    Summit" -- Hello, Scenic City Summit
  6. 15.

    greet name = "Hello, " ++ name greet "Scenic City

    Summit" -- Hello, Scenic City Summit
  7. 16.

    greet name = "Hello, " ++ name greet "Scenic City

    Summit" -- Hello, Scenic City Summit
  8. 17.

    greet name = "Hello, " ++ name greet "Scenic City

    Summit" -- Hello, Scenic City Summit Single Expression
  9. 18.

    greet name = "Hello, " ++ name greet "Scenic City

    Summit" -- Hello, Scenic City Summit
  10. 19.

    greet name = "Hello, " ++ name greet "Scenic City

    Summit" -- Hello, Scenic City Summit
  11. 23.

    add x y = x + y add 2 3

    == 5 add 2 3 == 5 add 2 3 == 5
  12. 24.

    add x y = x + y add 2 3

    == 5 add 2 3 == 5 add 2 3 == 5
  13. 25.

    add x y = x + y add 2 3

    == 5 add 2 3 == 5 add 2 3 == 5
  14. 27.

    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
  15. 28.

    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 ×
  16. 29.

    myList = [1, 2, 3, 4, 5] double n =

    n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
  17. 30.

    myList = [1, 2, 3, 4, 5] double n =

    n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
  18. 31.

    myList = [1, 2, 3, 4, 5] double n =

    n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
  19. 32.

    myList = [1, 2, 3, 4, 5] double n =

    n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
  20. 33.

    myList = [1, 2, 3, 4, 5] double n =

    n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
  21. 34.

    myList = [1, 2, 3, 4, 5] double n =

    n * 2 doubleNumbers list = List.map double list doubleNumbers myList -- [2, 4, 6, 8, 10]
  22. 36.

    add x y = x + y add 1 2

    -- 3 (add 1) 2 -- 3
  23. 37.

    add x y = x + y add 1 2

    -- 3 (add 1) 2 -- 3
  24. 38.

    add x y = x + y add 1 2

    -- 3 (add 1) 2 -- 3
  25. 39.

    add x y = x + y add 1 2

    -- 3 (add 1) 2 -- 3 New function created
  26. 44.

    greet name = "Hello, " ++ name exclaim phrase =

    phrase ++ "!" excitedGreeting name = exclaim (greet (String.toUpper name))
  27. 45.

    greet name = "Hello, " ++ name exclaim phrase =

    phrase ++ "!" excitedGreeting name = exclaim (greet (String.toUpper name))
  28. 56.

    Strong Static Types life : Int life = 42 greeting

    : String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
  29. 57.

    Strong Static Types life : Int life = 42 greeting

    : String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
  30. 58.

    Strong Static Types life : Int life = 42 greeting

    : String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
  31. 59.

    Strong Static Types life : Int life = 42 greeting

    : String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
  32. 60.

    Strong Static Types life : Int life = 42 greeting

    : String greeting = "Hello World" isTrue : Bool isTrue = True numbers : List Int numbers = [1, 2, 3]
  33. 61.

    greet : String -> String greet name = "Hello, "

    ++ name add : Int -> Int -> Int add x y = x + y
  34. 62.

    greet : String -> String greet name = "Hello, "

    ++ name add : Int -> Int -> Int add x y = x + y
  35. 63.

    greet : String -> String greet name = "Hello, "

    ++ name add : Int -> Int -> Int add x y = x + y
  36. 64.

    greet : String -> String greet name = "Hello, "

    ++ name add : Int -> (Int -> Int) add x y = x + y
  37. 65.

    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
  38. 67.

    dog : { name : String, age : Int }

    dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
  39. 68.

    dog : { name : String, age : Int }

    dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
  40. 69.

    dog : { name : String, age : Int }

    dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
  41. 70.

    dog : { name : String, age : Int }

    dog = { name = "Tucker" , age = 11 } dog.name -- "Tucker" dog.age -- 11 Records
  42. 71.

    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
  43. 72.

    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
  44. 73.

    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
  45. 74.

    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
  46. 75.

    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
  47. 76.

    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
  48. 78.

    type alias Dog = { name : String , age

    : Int , breed : Breed } type Breed = Sheltie | Poodle
  49. 79.

    type alias Dog = { name : String , age

    : Int , breed : Breed } type Breed = Sheltie | Poodle
  50. 80.

    type alias Dog = { name : String , age

    : Int , breed : Breed } type Breed = Sheltie | Poodle Union Type
  51. 81.

    dog : Dog dog = { name = "Tucker" ,

    age = 11 , breed = Sheltie }
  52. 82.

    dog : Dog dog = { name = "Tucker" ,

    age = 11 , breed = Sheltie }
  53. 83.

    dog : Dog dog = { name = "Tucker" ,

    age = 11 , breed = Sheltie }
  54. 84.

    dog : Dog dog = { name = "Tucker" ,

    age = 11 , breed = Shelty } Misspelled. Won’t compile!
  55. 88.

    type Maybe a = Just a | Nothing Wraps the

    successful value Type Variable
  56. 89.
  57. 90.

    type Maybe a = Just a | Nothing Either I

    have Just the value a, or I have Nothing.
  58. 91.

    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
  59. 92.

    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
  60. 93.

    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
  61. 94.

    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
  62. 95.

    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
  63. 96.

    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
  64. 97.

    case divide 4 2 of Just n -> "Result is

    " ++ (toString n) Nothing -> "No Result"
  65. 98.

    case divide 4 2 of Just n -> "Result is

    " ++ (toString n) Nothing -> "No Result"
  66. 99.

    case divide 4 2 of Just n -> "Result is

    " ++ (toString n) Nothing -> "No Result"
  67. 100.

    case divide 4 2 of Just n -> "Result is

    " ++ (toString n) Nothing -> "No Result"
  68. 101.

    case divide 4 2 of Just n -> "Result is

    " ++ (toString n) -- Nothing -> -- "No Result"
  69. 102.

    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!