Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Problemas que o Elm resolve
só com o compilador
sem nada mais
@cuducos
cuducos.me
1 / 73
2 / 73
3 / 73
4 / 73
5 / 73
6 / 73
“O melhor caso de uso de Haskell”
— Felipe de Morais
7 / 73
$ elm-make Main.elm  --warn
8 / 73
Propriedades que podem não existir
1
9 / 73
user = {
name: 'Eduardo Cuducos',
twitter: 'cuducos'
}
const getSocialMedia = (user) => user.facebook
getSocialMedia(user)...
user = {
name: 'Eduardo Cuducos',
twitter: 'cuducos'
}
const getSocialMedia = (user) => user.facebook
getSocialMedia(user)...
class User:
def __init__(self, name, twitter):
self.name = name
self.twitter = twitter
user = User('Eduardo Cuducos', 'cud...
class User:
def __init__(self, name, twitter):
self.name = name
self.twitter = twitter
user = User('Eduardo Cuducos', 'cud...
type alias User =
{ name : String
, twitter : String
}
getSocialMedia : User -> String
getSocialMedia user =
user.facebook...
type alias User =
{ name : String
, twitter : String
}
getSocialMedia : User -> String
getSocialMedia user =
user.facebook...
type alias User =
{ name : String
, twitter : String
}
getSocialMedia : User -> String
getSocialMedia user =
user.twitter
...
type alias User =
{ name : String
, twitter : String
}
getSocialMedia : User -> String
getSocialMedia user =
user.twitter
...
Elm não te deixa com
o undefined na mão!
18 / 73
Objetos que podem não existir
2
19 / 73
users = [
{ name: 'Eduardo Cuducos', twitter: 'cuducos' },
{ name: 'Hugo Bessa', twitter: 'hugobessaa' }
]
const firstUser...
users = [
{ name: 'Eduardo Cuducos', twitter: 'cuducos' },
{ name: 'Hugo Bessa', twitter: 'hugobessaa' }
]
const firstUser...
users = []
firstUserName(users)
22 / 73
users = []
firstUserName(users)
TypeError: Cannot read property 'name' of undefined
23 / 73
users = [
User('Eduardo Cuducos', 'cuducos'),
User('Hugo Bessa', 'hugobessaa')
]
def first_user_name(users):
return users[...
users = [
User('Eduardo Cuducos', 'cuducos'),
User('Hugo Bessa', 'hugobessaa')
]
def first_user_name(users):
return users[...
users = []
first_user_name(users)
26 / 73
users = []
first_user_name(users)
IndexError: list index out of range
27 / 73
users = []
first_user_name(users)
IndexError: list index out of range
def first_user_name(users):
first_user, *_ = users
r...
users = []
first_user_name(users)
IndexError: list index out of range
def first_user_name(users):
first_user, *_ = users
r...
firstUserName : List User -> String
firstUserName users =
let
firstUser = List.head users
in
firstUser.name
30 / 73
firstUserName : List User -> String
firstUserName users =
let
firstUser = List.head users
in
firstUser.name
-- TYPE MISMAT...
firstUserName : List User -> String
firstUserName users =
case List.head users of
Just user ->
user.name
Nothing ->
"User ...
firstUserName : List User -> String
firstUserName users =
case List.head users of
Just user ->
user.name
Nothing ->
"User ...
Elm te obri a a preparar a
aplicação para casos raros, extremos!
34 / 73
Missão impossível
3
35 / 73
const tomorrow = (today) => parseInt(today) + 1
tomorrow('18')
36 / 73
const tomorrow = (today) => parseInt(today) + 1
tomorrow('18')
19
37 / 73
tomorrow(undefined)
38 / 73
tomorrow(undefined)
NaN
39 / 73
def tomorrow(today):
return int(today) + 1
tomorrow('18')
40 / 73
def tomorrow(today):
return int(today) + 1
tomorrow('18')
19
41 / 73
tomorrow(None)
42 / 73
tomorrow(None)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
43 / 73
tomorrow(None)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
tomorrow('NaN')...
tomorrow(None)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
tomorrow('NaN')...
tomorrow : String -> Int
tomorrow today =
(String.toInt today) + 1
46 / 73
tomorrow : String -> Int
tomorrow today =
(String.toInt today) + 1
-- TYPE MISMATCH --------------------------------------...
tomorrow : String -> Int
tomorrow today =
case String.toInt today of
Ok day ->
day + 1
Err _ ->
Debug.crash "TODO"
48 / 73
tomorrow : String -> Int
tomorrow today =
case String.toInt today of
Ok day ->
day + 1
Err _ ->
Debug.crash "TODO"
Success...
Elm te obri a a se antecipar a erros
em tempo de execução.
50 / 73
Mas e o Debug.crash?
51 / 73
view : String -> Html msg
view today =
case String.toInt today of
Ok day ->
viewMyApp
Err error ->
viewErroMsg error
52 / ...
Ações de usuário não previstas
4
53 / 73
‑ 41 +
54 / 73
const counter = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return st...
const counter = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return st...
const counter = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return st...
const counter = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return st...
‑ 21 + x2
59 / 73
const render = () => ReactDOM.render(
<p>
<button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button>
{store.g...
const render = () => ReactDOM.render(
<p>
<button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button>
{store.g...
const render = () => ReactDOM.render(
<p>
<button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button>
{store.g...
type Msg = Increment | Decrement
update : Msg -> Int -> Int
update msg model =
case msg of
Increment -> model + 1
Decremen...
type Msg = Increment | Decrement
update : Msg -> Int -> Int
update msg model =
case msg of
Increment -> model + 1
Decremen...
view : Int -> Html Msg
view model =
p
[]
[ button [ onClick Increment ] [ text "+" ]
, text (toString model)
, button [ on...
view : Int -> Html Msg
view model =
p
[]
[ button [ onClick Increment ] [ text "+" ]
, text (toString model)
, button [ on...
type Msg = Increment | Decrement | Double
67 / 73
type Msg = Increment | Decrement | Double
-- MISSING PATTERNS --------------------------------------------------- Main.elm...
update : Msg -> Int -> Int
update msg model =
case msg of
Increment -> model + 1
Decrement -> model - 1
Double -> model * ...
update : Msg -> Int -> Int
update msg model =
case msg of
Increment -> model + 1
Decrement -> model - 1
Double -> model * ...
A arquitetura do Elm te dá arantia de que todas
as ações dos usuários estão previstas!
71 / 73
“Quem aprendeu al o novo hoje?”
— Raymond Hettin er
72 / 73
Muito obri ado : )
@cuducos
cuducos.me/blo
Vamos aprender Elm!
73 / 73
Upcoming SlideShare
Loading in …5
×

TDC2017 | São Paulo - Trilha Programação Funcional How we figured out we had a SRE team at - Problemas que o Elm resolve só com o compilador sem nada mais.

66 views

Published on

Trilha Programação Funcional How we figured out we had a SRE team at - Problemas que o Elm resolve só com o compilador sem nada mais.

Published in: Education
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (2019 Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download Full EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download Full doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download PDF EBOOK here { https://soo.gd/irt2 } ......................................................................................................................... Download EPUB Ebook here { https://soo.gd/irt2 } ......................................................................................................................... Download doc Ebook here { https://soo.gd/irt2 } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THIS can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THIS is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBooks .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THIS Helped Ignite a Movement,-- Atomic Habits: An Easy &amp; Proven Way to Build Good Habits &amp; Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THIS the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THIS Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

TDC2017 | São Paulo - Trilha Programação Funcional How we figured out we had a SRE team at - Problemas que o Elm resolve só com o compilador sem nada mais.

  1. 1. Problemas que o Elm resolve só com o compilador sem nada mais @cuducos cuducos.me 1 / 73
  2. 2. 2 / 73
  3. 3. 3 / 73
  4. 4. 4 / 73
  5. 5. 5 / 73
  6. 6. 6 / 73
  7. 7. “O melhor caso de uso de Haskell” — Felipe de Morais 7 / 73
  8. 8. $ elm-make Main.elm  --warn 8 / 73
  9. 9. Propriedades que podem não existir 1 9 / 73
  10. 10. user = { name: 'Eduardo Cuducos', twitter: 'cuducos' } const getSocialMedia = (user) => user.facebook getSocialMedia(user) 10 / 73
  11. 11. user = { name: 'Eduardo Cuducos', twitter: 'cuducos' } const getSocialMedia = (user) => user.facebook getSocialMedia(user) undefined 11 / 73
  12. 12. class User: def __init__(self, name, twitter): self.name = name self.twitter = twitter user = User('Eduardo Cuducos', 'cuducos') def get_social_media(user): return user.facebook get_social_media(user) 12 / 73
  13. 13. class User: def __init__(self, name, twitter): self.name = name self.twitter = twitter user = User('Eduardo Cuducos', 'cuducos') def get_social_media(user): return user.facebook get_social_media(user) AttributeError: 'User' object has no attribute 'facebook' 13 / 73
  14. 14. type alias User = { name : String , twitter : String } getSocialMedia : User -> String getSocialMedia user = user.facebook 14 / 73
  15. 15. type alias User = { name : String , twitter : String } getSocialMedia : User -> String getSocialMedia user = user.facebook -- TYPE MISMATCH ------------------------------------------------------ Main.elm `user` does not have a field named `facebook`. 15| user.facebook ^^^^^^^^^^^^^ The type of `user` is: User Which does not contain a field named `facebook`. Hint: The record fields do not match up. One has name and twitter. The other has facebook. 15 / 73
  16. 16. type alias User = { name : String , twitter : String } getSocialMedia : User -> String getSocialMedia user = user.twitter 16 / 73
  17. 17. type alias User = { name : String , twitter : String } getSocialMedia : User -> String getSocialMedia user = user.twitter Success! Compiled 1 module. 17 / 73
  18. 18. Elm não te deixa com o undefined na mão! 18 / 73
  19. 19. Objetos que podem não existir 2 19 / 73
  20. 20. users = [ { name: 'Eduardo Cuducos', twitter: 'cuducos' }, { name: 'Hugo Bessa', twitter: 'hugobessaa' } ] const firstUserName = (users) => users[0].name firstUserName(users) 20 / 73
  21. 21. users = [ { name: 'Eduardo Cuducos', twitter: 'cuducos' }, { name: 'Hugo Bessa', twitter: 'hugobessaa' } ] const firstUserName = (users) => users[0].name firstUserName(users) 'Eduardo Cuducos' 21 / 73
  22. 22. users = [] firstUserName(users) 22 / 73
  23. 23. users = [] firstUserName(users) TypeError: Cannot read property 'name' of undefined 23 / 73
  24. 24. users = [ User('Eduardo Cuducos', 'cuducos'), User('Hugo Bessa', 'hugobessaa') ] def first_user_name(users): return users[0].name first_user_name(users) 24 / 73
  25. 25. users = [ User('Eduardo Cuducos', 'cuducos'), User('Hugo Bessa', 'hugobessaa') ] def first_user_name(users): return users[0].name first_user_name(users) 'Eduardo Cuducos' 25 / 73
  26. 26. users = [] first_user_name(users) 26 / 73
  27. 27. users = [] first_user_name(users) IndexError: list index out of range 27 / 73
  28. 28. users = [] first_user_name(users) IndexError: list index out of range def first_user_name(users): first_user, *_ = users return first_use.name 28 / 73
  29. 29. users = [] first_user_name(users) IndexError: list index out of range def first_user_name(users): first_user, *_ = users return first_use.name ValueError: not enough values to unpack (expected at least 1, got 0) 29 / 73
  30. 30. firstUserName : List User -> String firstUserName users = let firstUser = List.head users in firstUser.name 30 / 73
  31. 31. firstUserName : List User -> String firstUserName users = let firstUser = List.head users in firstUser.name -- TYPE MISMATCH --------------------------------------------- Main.elm `firstUser` does not have a field named `name`. 29| firstUser.name ^^^^^^^^^^^^^^ The type of `firstUser` is: Maybe User Which does not contain a field named `name`. 31 / 73
  32. 32. firstUserName : List User -> String firstUserName users = case List.head users of Just user -> user.name Nothing -> "User not found" 32 / 73
  33. 33. firstUserName : List User -> String firstUserName users = case List.head users of Just user -> user.name Nothing -> "User not found" Success! Compiled 1 module. 33 / 73
  34. 34. Elm te obri a a preparar a aplicação para casos raros, extremos! 34 / 73
  35. 35. Missão impossível 3 35 / 73
  36. 36. const tomorrow = (today) => parseInt(today) + 1 tomorrow('18') 36 / 73
  37. 37. const tomorrow = (today) => parseInt(today) + 1 tomorrow('18') 19 37 / 73
  38. 38. tomorrow(undefined) 38 / 73
  39. 39. tomorrow(undefined) NaN 39 / 73
  40. 40. def tomorrow(today): return int(today) + 1 tomorrow('18') 40 / 73
  41. 41. def tomorrow(today): return int(today) + 1 tomorrow('18') 19 41 / 73
  42. 42. tomorrow(None) 42 / 73
  43. 43. tomorrow(None) TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' 43 / 73
  44. 44. tomorrow(None) TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' tomorrow('NaN') 44 / 73
  45. 45. tomorrow(None) TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' tomorrow('NaN') ValueError: invalid literal for int() with base 10: 'NaN' 45 / 73
  46. 46. tomorrow : String -> Int tomorrow today = (String.toInt today) + 1 46 / 73
  47. 47. tomorrow : String -> Int tomorrow today = (String.toInt today) + 1 -- TYPE MISMATCH ------------------------------------------------------ Main.elm The left argument of (+) is causing a type mismatch. 45| (String.toInt today) + 1 ^^^^^^^^^^^^^^^^^^ (+) is expecting the left argument to be a: number But the left argument is: Result String Int 47 / 73
  48. 48. tomorrow : String -> Int tomorrow today = case String.toInt today of Ok day -> day + 1 Err _ -> Debug.crash "TODO" 48 / 73
  49. 49. tomorrow : String -> Int tomorrow today = case String.toInt today of Ok day -> day + 1 Err _ -> Debug.crash "TODO" Success! Compiled 1 module. 49 / 73
  50. 50. Elm te obri a a se antecipar a erros em tempo de execução. 50 / 73
  51. 51. Mas e o Debug.crash? 51 / 73
  52. 52. view : String -> Html msg view today = case String.toInt today of Ok day -> viewMyApp Err error -> viewErroMsg error 52 / 73
  53. 53. Ações de usuário não previstas 4 53 / 73
  54. 54. ‑ 41 + 54 / 73
  55. 55. const counter = (state, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 } } 55 / 73
  56. 56. const counter = (state, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 } } const render = () => ReactDOM.render( <p> <button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button> {store.getState()} <button onClick={() => store.dispatch({ type: 'INCREMENT'})}>+</button> </p> ) 56 / 73
  57. 57. const counter = (state, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 } } const render = () => ReactDOM.render( <p> <button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button> {store.getState()} <button onClick={() => store.dispatch({ type: 'INCREMENT'})}>+</button> </p> ) + 57 / 73
  58. 58. const counter = (state, action) => { switch (action.type) { case 'INCREMENT': return state + 1 case 'DECREMENT': return state - 1 } } const render = () => ReactDOM.render( <p> <button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button> {store.getState()} <button onClick={() => store.dispatch({ type: 'INCREMENT'})}>+</button> </p> ) + 42 58 / 73
  59. 59. ‑ 21 + x2 59 / 73
  60. 60. const render = () => ReactDOM.render( <p> <button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button> {store.getSate()} <button onClick={() => store.dispatch({ type: 'INCREMENT'})}>+</button> <button onClick={() => store.dispatch({ type: 'DOUBLE'})}>x2</button> </p> ) 60 / 73
  61. 61. const render = () => ReactDOM.render( <p> <button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button> {store.getSate()} <button onClick={() => store.dispatch({ type: 'INCREMENT'})}>+</button> <button onClick={() => store.dispatch({ type: 'DOUBLE'})}>x2</button> </p> ) x2 61 / 73
  62. 62. const render = () => ReactDOM.render( <p> <button onClick={() => store.dispatch({ type: 'DECREMENT'})}>-</button> {store.getSate()} <button onClick={() => store.dispatch({ type: 'INCREMENT'})}>+</button> <button onClick={() => store.dispatch({ type: 'DOUBLE'})}>x2</button> </p> ) x2 21 62 / 73
  63. 63. type Msg = Increment | Decrement update : Msg -> Int -> Int update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 view : Int -> Html Msg view model = p [] [ button [ onClick Increment ] [ text "+" ] , text (toString model) , button [ onClick Decrement ] [ text "-" ] ] 63 / 73
  64. 64. type Msg = Increment | Decrement update : Msg -> Int -> Int update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 view : Int -> Html Msg view model = p [] [ button [ onClick Increment ] [ text "+" ] , text (toString model) , button [ onClick Decrement ] [ text "-" ] ] ‑ 21 + 64 / 73
  65. 65. view : Int -> Html Msg view model = p [] [ button [ onClick Increment ] [ text "+" ] , text (toString model) , button [ onClick Decrement ] [ text "-" ] , button [ onClick Double ] [ text "2x" ] ] 65 / 73
  66. 66. view : Int -> Html Msg view model = p [] [ button [ onClick Increment ] [ text "+" ] , text (toString model) , button [ onClick Decrement ] [ text "-" ] , button [ onClick Double ] [ text "2x" ] ] -- NAMING ERROR ------------------------------------------------------- Main.elm Cannot find variable `Double` 82| , button [ onClick Double ] [ text "2x" ] 66 / 73
  67. 67. type Msg = Increment | Decrement | Double 67 / 73
  68. 68. type Msg = Increment | Decrement | Double -- MISSING PATTERNS --------------------------------------------------- Main.elm This `case` does not have branches for all possibilities. 68|> case msg of 69|> Increment -> 70|> model + 1 71|> 72|> Decrement -> 73|> model - 1 You need to account for the following values: Main.Double Add a branch to cover this pattern! 68 / 73
  69. 69. update : Msg -> Int -> Int update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 Double -> model * 2 69 / 73
  70. 70. update : Msg -> Int -> Int update msg model = case msg of Increment -> model + 1 Decrement -> model - 1 Double -> model * 2 Success! Compiled 1 module. 70 / 73
  71. 71. A arquitetura do Elm te dá arantia de que todas as ações dos usuários estão previstas! 71 / 73
  72. 72. “Quem aprendeu al o novo hoje?” — Raymond Hettin er 72 / 73
  73. 73. Muito obri ado : ) @cuducos cuducos.me/blo Vamos aprender Elm! 73 / 73

×