usando pop com programação funcional

59

Upload: tales-andrade

Post on 12-Feb-2017

236 views

Category:

Engineering


2 download

TRANSCRIPT

Page 1: Usando POP com Programação Funcional
Page 2: Usando POP com Programação Funcional

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

Page 3: Usando POP com Programação Funcional

Compartilhando código e dependências entre plataformas

Escrevendo uma vez e reutilizando em iOS, tvOS, watchOS, macOS 😂

Page 4: Usando POP com Programação Funcional

Ou…

…veja bem…

Page 5: Usando POP com Programação Funcional

Como alterei o tema da minha palestra

E esqueci de enviar a atualização

Page 6: Usando POP com Programação Funcional

Usando POP com Programação Funcional

Como entender algumas abstrações usando Protocol Oriented Programming

Page 7: Usando POP com Programação Funcional

A Formula

• Descreva em linguagem natural• Escreva a assinatura do tipo• Implemente a logica• Teste seu código(não necessariamente nessa ordem)

Page 8: Usando POP com Programação Funcional

O que é programação funcional?

• Estilo de programação• First Class Functions• Modularização• Efeitos colaterais• Imutabilidade

Page 9: Usando POP com Programação Funcional

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 ofthe 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.

Page 10: Usando POP com Programação Funcional

Três protocolos/conceitos

Page 11: Usando POP com Programação Funcional

protocol Concattable { init() func +(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self}

Page 12: Usando POP com Programação Funcional

extension Concattable { static func concat(list: [Self]) -> Self { return list.reduce(Self(), combine: +) }}

Page 13: Usando POP com Programação Funcional

extension Int: Concattable {}extension Float: Concattable {}extension String: Concattable {}extension Array: Concattable {}

Page 14: Usando POP com Programação Funcional

func +<T>(left: Set<T>, right: Set<T>) -> Set<T> { return left.union(right)}

func +(left: Bool, right: Bool) -> Bool { return left || right}

Page 15: Usando POP com Programação Funcional

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) }}

Page 16: Usando POP com Programação Funcional

protocol Concattable { init() func +(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self}

Page 17: Usando POP com Programação Funcional

protocol Concattable { init() static func concat(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self}

Page 18: Usando POP com Programação Funcional

protocol Concattable { func makeEmpty() -> Self func concat(left: Self, right: Self) -> Self func concat(list: [Self]) -> Self}

Page 19: Usando POP com Programação Funcional

protocol Concattable { static func empty() -> Self static func append(left: Self, right: Self) -> Self static func concat(list: [Self]) -> Self}

Page 20: Usando POP com Programação Funcional

protocol Concattable { static func empty() -> Self static func append(Self, Self) -> Self static func concat([Self]) -> Self}

Page 21: Usando POP com Programação Funcional

protocol Concattable { static func empty() -> m static func append(m, m) -> m static func concat([m]) -> m}

Page 22: Usando POP com Programação Funcional

protocol Mappable { associatedtype Element func map<OutType>(transform: Element -> OutType) -> Self<OutType>}

Page 23: Usando POP com Programação Funcional

protocol Mappable { associatedtype Element static func map<OutType, OutMappable: Mappable where Element == OutType>( transform: (Element -> OutType) ) -> OutMappable}

Page 24: Usando POP com Programação Funcional

extension Array: Mappable { func map<OutType>(transform: (Element -> OutType)) -> [OutType] { var result = Array<OutType>() for e in self { result.append(transform(e)) } return result }}

Page 25: Usando POP com Programação Funcional

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)) } }}

Page 26: Usando POP com Programação Funcional

protocol Mappable { associatedtype Element func map<OutType, OutMappable: Mappable where Element == OutType>( transform: (Element -> OutType) ) -> OutMappable}

Page 27: Usando POP com Programação Funcional

protocol Mappable { associatedtype Element func map<A, B>(transform: A -> B, input: Self<A>) -> Self<B>}

Page 28: Usando POP com Programação Funcional

protocol Mappable { func map(transform: a -> b, input: Self a) -> Self b}

Page 29: Usando POP com Programação Funcional

protocol Mappable { func map(a -> b, Self a) -> Self b}

Page 30: Usando POP com Programação Funcional

protocol FlatMappable: Mappable { init(element: Element) func flatMap<Out>(transform: Element -> Self<Out>) -> Self<Out>}

Page 31: Usando POP com Programação Funcional

protocol FlatMappable: Mappable { init(element: Element) func flatMap<OutType, OutMappable: FlatMappable where Element == OutType>( transform: Element -> OutType) -> OutMappable}

Page 32: Usando POP com Programação Funcional

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) } }}

Page 33: Usando POP com Programação Funcional

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

Page 34: Usando POP com Programação Funcional

Futures

Future precisa de:

• Contexto de execução• Tarefa a ser executada

Page 35: Usando POP com Programação Funcional

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() } }}

Page 36: Usando POP com Programação Funcional

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!) } } } }}

Page 37: Usando POP com Programação Funcional

class Promise<T>: Future<T> { func success(v: T) { } func failure(e: NSError) { }}

Page 38: Usando POP com Programação Funcional

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)}

Page 39: Usando POP com Programação Funcional

protocol FlatMappable: Mappable { init(element: Element) func flatMap<Out>(transform: Element -> Self<Out>) -> Self<Out>}

Page 40: Usando POP com Programação Funcional

protocol Bindable: Mappable { init(element: Element) func bind<Out>( input: Self<In>, transform: In -> Self<Out>) -> Self<Out>}

Page 41: Usando POP com Programação Funcional

protocol FlatMappable: Mappable { func empty() -> m func flatMap(a -> m b) -> m b}

Page 42: Usando POP com Programação Funcional

Para fins educacionais

protocol ~> class

Page 43: Usando POP com Programação Funcional

protocol Concattable { func empty() -> m func append(m, m) -> m func concat([m]) -> m}

Page 44: Usando POP com Programação Funcional

class Monoid m wheremempty :: mmappend :: m -> m -

> mmconcat :: [m] -> m

Page 45: Usando POP com Programação Funcional

Ja falamos de

Monoid

Page 46: Usando POP com Programação Funcional

protocol Mappable { func map(a -> b, Self a) -> Self b}

Page 47: Usando POP com Programação Funcional

class Functor f wherefmap :: (a -> b) -> f a -

> f b

Page 48: Usando POP com Programação Funcional

Ja falamos de

MonoidFunctor

Page 49: Usando POP com Programação Funcional

protocol FlatMappable: Mappable { func empty() -> m func flatMap(a -> m b) -> m b}

Page 50: Usando POP com Programação Funcional

class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b

Page 51: Usando POP com Programação Funcional

Ja falamos de

MonoidFunctorMonad

Page 52: Usando POP com Programação Funcional

De modo simples..

protocol ~> classConcattable ~> MonoidMappable ~> Functor

FlatMappable ~> Monad

Page 53: Usando POP com Programação Funcional

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?

Page 54: Usando POP com Programação Funcional

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

Page 55: Usando POP com Programação Funcional

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

Page 56: Usando POP com Programação Funcional

Outras coisas que podem ser criadas com monads

• Frameworks reativos• DSL• trabalho com coleções (LINQ)

Page 57: Usando POP com Programação Funcional

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

Page 58: Usando POP com Programação Funcional

Outras referências

@[email protected]

Obrigado :)

Page 59: Usando POP com Programação Funcional

www.concretesolutions.com.brblog.concretesolutions.com.br

Rio de Janeiro – Rua São José, 90 – cj. 2121Centro – (21) 2240-2030

São Paulo - Rua Sansão Alves dos Santos, 433 4º andar - Brooklin - (11) 4119-0449