Contratos fortes com programação funcional

Contratos fortes com programação funcional

O paradigma funcional, infelizmente, está repleto de buzz-words que complicam a vida de quem quer aprendê-lo. Sem falar nos inúmeros tutoriais que ficam apenas nos princípios e não se preocupam em trazê-los para o dia-a-dia do desenvolvedor.

Nessa talk iremos modelar um fluxo de cadastro e mostrar falhas de design e problemas que afetam desenvolvedores e usuários. A partir disso mostraremos duas possíveis soluções, com e sem programação funcional, seus pontos positivos e negativos e porque acreditamos que a solução com programação funcional se mostra mais elegante.

6c63aa49d093296885859211d1991962?s=128

Rafael Machado

November 28, 2019
Tweet

Transcript

  1. 4.
  2. 8.

    ?

  3. 10.
  4. 11.

    “ Apoia-se em funções, modeladas como funções matemáticas Em sua

    essência, programas são uma combinação de expressões
  5. 16.

    class FistStepViewController { func continueButtonTouched(_ sender: UIButton) { let registration

    = Registration() registration.name = textField.text router.navigateToSecondStep(registration) } } Backend Input de nome Input de email Input de senha
  6. 17.

    class SecondStepViewController { func continueButtonTouched(_ sender: UIButton) { registration.email =

    textField.text router.navigateToThirdStep(registration) } } Backend Input de nome Input de email Input de senha
  7. 18.

    class ThirdStepViewController { func registerButtonTouched(_ sender: UIButton) { registration.password =

    textField.text network.postRegistration(registration) } } Backend Input de nome Input de email Input de senha
  8. 19.

    class Network { func postRegistration(_ registration: Registration) { guard let

    name = registration.name, let email = registration.email, let password = registration.password else { NSLog("Something is wrong, registration *must* not be empty") return } Alamofire.request( url: registrationUrl, method: .post, parameters: [ "name": name, "email": email, "password": password ] ) } } Backend Input de nome Input de email Input de senha
  9. 22.

    struct SecondStepModel { let name: Name let email: Email init(firstStep:

    FirstStepModel, email: Email) { self.name = firstStep.name self.email = email } }
  10. 23.

    struct ThirdStepModel { let name: Name let email: Email let

    password: Password init(secondStep: SecondStepModel, password: Password) { self.name = secondStep.name self.email = secondStep.email self.password = password } }
  11. 25.
  12. 26.

    “ Converte uma função que recebe vários argumentos para uma

    sequência de funções, cada uma recebendo com um único argumento
  13. 33.

    func curry<A, B, C, D>(_ f: @escaping (A, B, C)

    "-> D) "-> (A) "-> (B) "-> (C) "-> D { }
  14. 34.

    func curry<A, B, C, D>(_ f: @escaping (A, B, C)

    "-> D) "-> (A) "-> (B) "-> (C) "-> D { return { a in } }
  15. 35.

    func curry<A, B, C, D>(_ f: @escaping (A, B, C)

    "-> D) "-> (A) "-> (B) "-> (C) "-> D { return { a in { b in } } }
  16. 36.

    func curry<A, B, C, D>(_ f: @escaping (A, B, C)

    "-> D) "-> (A) "-> (B) "-> (C) "-> D { return { a in { b in { c in return f(a, b, c) } } } }
  17. 38.

    typealias InitialStep = (Name) "-> (Email) "-> (Password) "-> Registration

    typealias FirstStep = (Email) "-> (Password) "-> Registration typealias SecondStep = (Password) "-> Registration
  18. 39.

    class FistStepViewController { func continueButtonTouched(_ sender: UIButton) { let initialData:

    InitialStep = curry(Registration.init) let partialData = initialData(textField.text) router.navigateToSecondStep(partialData) } } Backend Input de nome Input de email Input de senha
  19. 40.

    class SecondStepViewController { func continueButtonTouched(_ sender: UIButton) { let partialData

    = self.partialData(textField.text) router.navigateToThirdStep(partialData) } } Backend Input de nome Input de email Input de senha
  20. 41.

    class ThirdStepViewController { func registerButtonTouched(_ sender: UIButton) { let registration

    = self.partialData(textField.text) network.postRegistration(registration) } } Backend Input de nome Input de email Input de senha
  21. 42.

    class Network { func postRegistration(_ registration: Registration) { Alamofire.request( url:

    registrationUrl, method: .post, parameters: [ "name": registration.name, "email": registration.email, "password": registration.password ] ) } } Backend Input de nome Input de email Input de senha
  22. 43.
  23. 44.

    ?

  24. 45.