usando pop com programação funcional

Post on 12-Feb-2017

236 Views

Category:

Engineering

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

Compartilhando código e dependências entre plataformas

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

Ou…

…veja bem…

Como alterei o tema da minha palestra

E esqueci de enviar a atualização

Usando POP com Programação Funcional

Como entender algumas abstrações usando Protocol Oriented Programming

A Formula

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

O que é programação funcional?

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

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.

Três protocolos/conceitos

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Futures

Future precisa de:

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

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

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

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

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

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

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

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

Para fins educacionais

protocol ~> class

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

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

> mmconcat :: [m] -> m

Ja falamos de

Monoid

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

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

> f b

Ja falamos de

MonoidFunctor

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

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

Ja falamos de

MonoidFunctorMonad

De modo simples..

protocol ~> classConcattable ~> MonoidMappable ~> Functor

FlatMappable ~> Monad

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?

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

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

Outras coisas que podem ser criadas com monads

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

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

Outras referências

@talesptales.andrade@concretesolutions.com.br

Obrigado :)

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

top related