O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Usando POP com Programação Funcional

387 visualizações

Publicada em

Como entender algumas abstrações usando Protocol Oriented Programming

Publicada em: Engenharia
  • Seja o primeiro a comentar

Usando POP com Programação Funcional

  1. 1. Quem sou eu • Mestre em Computação pelo IME-USP • Desenvolvedor C desde 2002 • Objective-C desde 2007 (coisas básicas em Mac OS X antes do iPhone!) • iOS desde 2010 • Swift desde Agosto/2015 • Tech Lead na Concrete Solutions (estamos contratando) • Organizador do CocoaHeads SP • Colaborador do CocoaHeads BR • Colaborador da Embaixada Brasileira de Appsterdam
  2. 2. Compartilhando código e dependências entre plataformas Escrevendo uma vez e reutilizando em iOS, tvOS, watchOS, macOS 😂
  3. 3. Ou… …veja bem…
  4. 4. Como alterei o tema da minha palestra E esqueci de enviar a atualização
  5. 5. Usando POP com Programação Funcional Como entender algumas abstrações usando Protocol Oriented Programming
  6. 6. A Formula • Descreva em linguagem natural • Escreva a assinatura do tipo • Implemente a logica • Teste seu código (não necessariamente nessa ordem)
  7. 7. O que é programação funcional? • Estilo de programação • First Class Functions • Modularização • Efeitos colaterais • Imutabilidade
  8. 8. O que é programação funcional? A monad is just a monoid in the category of endofunctors, what's the problem? Crockford’s Law In addition to its being good and useful, it's also cursed. The curse of the monad is that once you get the epiphany, once you understand oh, that's what it is, you lose the ability to explain it to anybody else.
  9. 9. Três protocolos/conceitos
  10. 10. protocol Concattable { init() func +(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self }
  11. 11. extension Concattable { static func concat(list: [Self]) -> Self { return list.reduce(Self(), combine: +) } }
  12. 12. extension Int: Concattable {} extension Float: Concattable {} extension String: Concattable {} extension Array: Concattable {}
  13. 13. func +<T>(left: Set<T>, right: Set<T>) -> Set<T> { return left.union(right) } func +(left: Bool, right: Bool) -> Bool { return left || right }
  14. 14. func +<Key, Value>(inout left: Dictionary<Key, Value>, right:Dictionary<Key, Value>) -> Dictionary<Key, Value> { for (key, value) in right { left.updateValue(value, forKey: key) } }
  15. 15. protocol Concattable { init() func +(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self }
  16. 16. protocol Concattable { init() static func concat(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self }
  17. 17. protocol Concattable { func makeEmpty() -> Self func concat(left: Self, right: Self) -> Self func concat(list: [Self]) -> Self }
  18. 18. protocol Concattable { static func empty() -> Self static func append(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self }
  19. 19. protocol Concattable { static func empty() -> Self static func append(Self, Self) -> Self static func concat([Self]) -> Self }
  20. 20. protocol Concattable { static func empty() -> m static func append(m, m) -> m static func concat([m]) -> m }
  21. 21. protocol Mappable { associatedtype Element func map<OutType>(transform: Element -> OutType) -> Self<OutType> }
  22. 22. protocol Mappable { associatedtype Element static func map<OutType, OutMappable: Mappable where Element == OutType>( transform: (Element -> OutType) ) -> OutMappable }
  23. 23. extension Array: Mappable { func map<OutType>(transform: (Element -> OutType)) -> [OutType] { var result = Array<OutType>() for e in self { result.append(transform(e)) } return result } }
  24. 24. enum Result<ValueType>: Mappable { case Failure(error: ErrorType) case Success(value: ValueType) func map<OutType>(transform: ValueType -> OutType) -> Result<OutType> { switch self { case .Failure(let error): return .Failure(error) case .Success(let value): return .Success(value: transform(value)) } } }
  25. 25. protocol Mappable { associatedtype Element func map<OutType, OutMappable: Mappable where Element == OutType>( transform: (Element -> OutType) ) -> OutMappable }
  26. 26. protocol Mappable { associatedtype Element func map<A, B>(transform: A -> B, input: Self<A>) -> Self<B> }
  27. 27. protocol Mappable { func map(transform: a -> b, input: Self a) -> Self b }
  28. 28. protocol Mappable { func map(a -> b, Self a) -> Self b }
  29. 29. protocol FlatMappable: Mappable { init(element: Element) func flatMap<Out>(transform: Element -> Self<Out>) -> Self<Out> }
  30. 30. protocol FlatMappable: Mappable { init(element: Element) func flatMap<OutType, OutMappable: FlatMappable where Element == OutType>( transform: Element -> OutType) -> OutMappable }
  31. 31. extension Optional: FlatMappable { typealias Element = Wrapped func flatMap<Out>(transform: Wrapped -> Optional<Out>) -> Optional<Out> { switch self { case .None: return nil case .Some(let value): return transform(value) } } }
  32. 32. Futures e Promises Future - objeto mantendo um valor que pode estar disponível em algum momento • se o bloco de execução não terminou, dizemos que o Future ainda não terminou • ao completar a execução, temos um valor ou um erro - Result FTW Promise - “extensão” do Future • Pode retornar um Future • Promise pode não completar/executar • read/write
  33. 33. Futures Future precisa de: • Contexto de execução • Tarefa a ser executada
  34. 34. class Future<T> { typealias Runnable = () -> Result<T> typealias OnSuccessCallBack = (T) -> () typealias OnFailueCallBack = (NSError) -> () typealias OnComplete = (result: Result<T>) - //wrapper de dispatch_queue_t > () let extension: ExecutionContext var result: Result<T>? = nil { didSet { self.performCallbacks() } } }
  35. 35. extension Future { func then<U>(executor: ExecutionContext = ExecutionContext.defaultContext, task: (value: T) -> Result<U>) -> Future<U> { let future = Future<U>() self.onComplete() { result in switch result { case .Error(let e): syncronized(future) { future.result = Result<U>(e) } case .Value(let v): future.execute(executor) { return task(value: result.value!) } } } } }
  36. 36. class Promise<T>: Future<T> { func success(v: T) { } func failure(e: NSError) { } }
  37. 37. future { if let cached = self.cachedData() { cached.success(cachedData) } return retriveData(url).flatMap( deserialize($0)) }.onSuccess { items in self.updateUI(items) self.cacheItems(items) } cached.onSuccess { items in self.updateUI(items) }
  38. 38. protocol FlatMappable: Mappable { init(element: Element) func flatMap<Out>(transform: Element -> Self<Out>) -> Self<Out> }
  39. 39. protocol Bindable: Mappable { init(element: Element) func bind<Out>( input: Self<In>, transform: In -> Self<Out>) -> Self<Out> }
  40. 40. protocol FlatMappable: Mappable { func empty() -> m func flatMap(a -> m b) -> m b }
  41. 41. Para fins educacionais protocol ~> class
  42. 42. protocol Concattable { func empty() -> m func append(m, m) -> m func concat([m]) -> m }
  43. 43. class Monoid m where mempty :: m mappend :: m -> m -> m mconcat :: [m] -> m
  44. 44. Ja falamos de Monoid
  45. 45. protocol Mappable { func map(a -> b, Self a) -> Self b }
  46. 46. class Functor f where fmap :: (a -> b) -> f a -> f b
  47. 47. Ja falamos de Monoid Functor
  48. 48. protocol FlatMappable: Mappable { func empty() -> m func flatMap(a -> m b) -> m b }
  49. 49. class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  50. 50. Ja falamos de Monoid Functor Monad
  51. 51. De modo simples.. protocol ~> class Concattable ~> Monoid Mappable ~> Functor FlatMappable ~> Monad
  52. 52. A monad is just a monoid in the category of endofunctors, what's the problem? http://stackoverflow.com/questions/3870088/a-monad-is-just-a-monoid-in-the- category-of-endofunctors-whats-the-issue Incompleto: piada criada em “A Brief, Incomplete, and Mostly Wrong History of Programming Languages” Qual o problema?
  53. 53. Então, o que é uma Monad? All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor. A monad is just a monoid in the category of endofunctors, what's the problem? Vs
  54. 54. Então, o que é uma Monad? Uma forma de criar complexidade, partindo de simplicidade Monads famosas em Haskell (ainda não implementadas em Swift) • I/O Monad • State Monad • Reader/Writer Monad • Continuation Monad
  55. 55. Outras coisas que podem ser criadas com monads • Frameworks reativos • DSL • trabalho com coleções (LINQ)
  56. 56. Outras referências • Finally Understand Monads with this One Weird Trick by Andy Bartholomew • Monads are Not Monsters by Junior Bontognali • Don’t Fear the Monads by Bryan Beckman • Abstraction, intuition, and the “monad tutorial fallacy” by Brent • Haskell for Mac - App Store
  57. 57. Outras referências @talesp tales.andrade@concretesolutions.com.br Obrigado :)
  58. 58. www.concretesolutions.com.br blog.concretesolutions.com.br Rio de Janeiro – Rua São José, 90 – cj. 2121 Centro – (21) 2240-2030 São Paulo - Rua Sansão Alves dos Santos, 433 4º andar - Brooklin - (11) 4119-0449

×