SlideShare une entreprise Scribd logo
1  sur  48
Télécharger pour lire hors ligne
Promise of an API
Maxim Zaks (@iceX33)
CocoaHeads Berlin
Agenda
— Consume a promise
— Produce a promise
— Swift
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2;
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2;
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
withError:(NSError**)error;
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2;
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
withError:(NSError**)error;
- (void)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
withBlock:(void (^)(NSNumber *sum, NSError *error))block;
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2;
- (NSNumber*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
withError:(NSError**)error;
- (void)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
withBlock:(void (^)(NSNumber *sum, NSError *error))block;
- (void)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
success:(void (^)(NSNumber *sum))success
failure:(void (^)(NSError *error))failur;
And now with a real promise!
- (OMPromise*)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2;
What is a promise
(OMPromise)?
It's just an object
It has state
— Unfulfilled
— Fulfilled
— Failed
It has other properties
— result
— error
— progress*
It has methods
- (OMPromise *)fulfilled:(void (^)(id result))fulfilHandler;
- (OMPromise *)failed:(void (^)(NSError *error))failHandler;
- (OMPromise *)progressed:(void (^)(float progress))progressHandler;
It lets you call handlers on a custom queue
- (OMPromise *)fulfilled:(void (^)(id result))fulfilHandler on:(dispatch_queue_t)queue;
- (OMPromise *)failed:(void (^)(NSError *error))failHandler on:(dispatch_queue_t)queue;
- (OMPromise *)progressed:(void (^)(float progress))progressHandler on:(dispatch_queue_t)queue;
So let's see it in action
OMPromise *sum = [calc addFirstNumber:@3 toSecondNumber:@2];
[[sum fulfilled:^(id result){
NSLog(@"Sum: %@", result);
}] failed:^(NSError *error){
NSLog(@"Failed to calculate because of: %@", error);
}];
Concatenation
sum1 = 3 + 2
sum2 = sum1 + 2
sum3 = sum1 + 3
Concatenation
OMPromise *sum1 = [calc addFirstNumber:@3 toSecondNumber:@2];
OMPromise *sum2 = [sum1 than:^(NSNumber *n1){
return [calc addFirstNumber:n1 toSecondNumber:@2];
}];
OMPromise *sum3 = [sum1 than:^(NSNumber *n1){
return [calc addFirstNumber:n1 toSecondNumber:@3];
}];
[[[OMPromise all:@[sum1, sum2, sum3]] fulfilled:^(NSArray *results){
NSLog(@"Sum1: %@, Sum2: %@, Sum3: %@", results[0], results[1], results[2]);
} on:dispatch_get_main_queue()] failed:^(NSError *error){
NSLog(@"Failed to calculate because of: %@", error);
} on:dispatch_get_main_queue()];
Deep chaining
OMPromise *sum = [OMPromise chain:[
^(NSNumber *n1){
return [calc addFirstNumber:@2 toSecondNumber:@3];
},
^(NSNumber *n1){
return [calc addFirstNumber:n1 toSecondNumber:@3];
},
^(NSNumber *n1){
return [calc addFirstNumber:n1 toSecondNumber:@2];
}
] initial:nil];
Recovering from failed promise
OMPromise *sum1 = [calc addFirstNumber:@3 toSecondNumber:@2];
OMPromise *rescuedSum = [sum1 rescue:^(NSError *error){
NSLog(@"Shit happens! %@", error);
return @0;
}];
Recap 1/3
@interface OMPromise : NSObject
@property(assign, readonly, nonatomic) OMPromiseState state;
@property(readonly, nonatomic) id result;
@property(readonly, nonatomic) NSError *error;
@property(assign, readonly, nonatomic) float progress;
Recap 2/3
- (OMPromise *)fulfilled:(void (^)(id result))fulfilHandler;
- (OMPromise *)failed:(void (^)(NSError *error))failHandler;
- (OMPromise *)progressed:(void (^)(float progress))progressHandler;
- (OMPromise *)then:(id (^)(id result))thenHandler;
- (OMPromise *)rescue:(id (^)(NSError *error))rescueHandler;
Recap 3/3
+ (OMPromise *)chain:(NSArray *)thenHandlers initial:(id)result;
+ (OMPromise *)any:(NSArray *)promises;
+ (OMPromise *)all:(NSArray *)promises;
Now what's about creating a
promise?
Convenience methods on OMPromise
+ (OMPromise *)promiseWithResult:(id)result;
+ (OMPromise *)promiseWithResult:(id)result after:(NSTimeInterval)delay;
+ (OMPromise *)promiseWithError:(NSError *)error;
+ (OMPromise *)promiseWithTask:(id (^)())task;
Example for success
- (OMPromise *)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
{
return [OMPromise promiseWithTask:^{
return @([n1 intValue] + [n2 intValue])
}];
}
Example for error
- (OMPromise *)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
{
return [OMPromise promiseWithTask:^{
return [NSError new];
}];
}
And what is the non convenient
way?
Defered object
@interface OMDeferred : OMPromise
+ (OMDeferred *)deferred;
- (OMPromise *)promise;
- (void)fulfil:(id)result;
- (void)fail:(NSError *)error;
- (void)progress:(float)progress;
@end
Example
- (OMPromise *)addFirstNumber:(NSNumber*)number1
toSecondNumber:(NSNumber*)number2
{
OMDeferred *deferred = [OMDeferred deferred];
dispatch_async(dispatch_get_global_queue(0, 0), ^
{
NSError *error = nil;
NSNumber *sum = [self addFirstNumber:number1
toSecondNumber:number2
withError:&error];
if(error){
[deferred fail:error];
} else {
[deferred fulfill:sum];
}
});
return deferred.promise;
}
Recap
— Promise is an immutable data structure
— Deferred is a subclass of Promise which makes it
mutable
To add up confusion I
implemented promises in
Swift
First attempt was just to
port it
Using Enums for state representation feels right
enum PromiseState{
case Unfulfilled
case Fulfilled
case Failed
}
I need inheritance so let's
use classes
Using constants as read only property is not a good
idea as you have to set them directly in the
initializer
class Promise<T> {
let state : PromiseState
let result : T
let error : NSError
}
Switching to var makes it work but Promise is not
immutable any more
class Promise<T> {
var state : PromiseState
var result : T?
var error : NSError?
init(){
state = .Unfulfilled
}
func fulfill(value : T){
result = value
state = .Fulfilled
}
}
Trying to make a read only property
class Promise<T> {
var state : PromiseState
var result : T? {
get {
return self.result
}
}
var error : NSError?
init(){
state = .Unfulfilled
}
}
Sadly this was an infinite loop
— There are no Read-Only properties in Swift
— Only Read-Only Computed Properties
Schock number 2
— There are no ivars in Swift
— And no visibility constrains (but they promised
to introduced those)
After initial shock pass, I
decided to go functional
func future<T>(execution : ()->FutureResult<T>)(handler: FutureHandler<T>) {
var result : FutureResult<T>?
var done = false
dispatch_async(dispatch_get_global_queue(0, 0)) {
result = execution()
done = true
}
dispatch_async(dispatch_get_global_queue(0, 0)) {
while !done {}
dispatch_async(dispatch_get_main_queue()) {
switch handler {
case .FulFilled(let fulfilled):
switch result! {
case .Result(let value):
fulfilled(value())
case .Error : println("can't process error")
}
case .Failed(let failed):
switch result! {
case .Result: println("can't process result")
case .Error(let error) : failed(error())
}
}
}
}
}
Main concept = currying
func add(n1:Int)(n2:Int) -> Int {
return n1 + n2
}
let increaseByTwo = add(2)
let sum = increaseByTwo(3)
Using enums with Associated Values
enum FutureHandler<T>{
case FulFilled((T)->())
case Failed((NSError)->())
}
enum FutureResult<T>{
case Result(@auto_closure ()->T)
case Error(@auto_closure ()->NSError)
}
Here is how you can use it:
var f = future {
FutureResult.Result(2 + 3)
}
f (handler: FutureHandler.FulFilled {
result in
println("Promise fulfilled : (result)")
})
It's not a beauty but it
works
However you can't concatenate futures in this
implementation
— typealias F = (FutureHandler<Int>) -> F
For the tough ones, who survived this talk:
— https://github.com/b52/OMPromises
— https://github.com/mzaks/siwft-future
Thank you!
Maxim Zaks (@iceX33)

Contenu connexe

Tendances

Tendances (20)

Rust
RustRust
Rust
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, code
 
Mcrl2 by kashif.namal@gmail.com, adnanskyousafzai@gmail.com
Mcrl2 by kashif.namal@gmail.com, adnanskyousafzai@gmail.comMcrl2 by kashif.namal@gmail.com, adnanskyousafzai@gmail.com
Mcrl2 by kashif.namal@gmail.com, adnanskyousafzai@gmail.com
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
The Ring programming language version 1.8 book - Part 88 of 202
The Ring programming language version 1.8 book - Part 88 of 202The Ring programming language version 1.8 book - Part 88 of 202
The Ring programming language version 1.8 book - Part 88 of 202
 
ReactiveCocoa workshop
ReactiveCocoa workshopReactiveCocoa workshop
ReactiveCocoa workshop
 
Lambda выражения и Java 8
Lambda выражения и Java 8Lambda выражения и Java 8
Lambda выражения и Java 8
 
The Ring programming language version 1.5.3 book - Part 89 of 184
The Ring programming language version 1.5.3 book - Part 89 of 184The Ring programming language version 1.5.3 book - Part 89 of 184
The Ring programming language version 1.5.3 book - Part 89 of 184
 
Rcpp11 useR2014
Rcpp11 useR2014Rcpp11 useR2014
Rcpp11 useR2014
 
'Getting' Clojure - '(parentheses are just hugs for your code)
'Getting' Clojure - '(parentheses are just hugs for your code)'Getting' Clojure - '(parentheses are just hugs for your code)
'Getting' Clojure - '(parentheses are just hugs for your code)
 
The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202
 
Clojure+ClojureScript Webapps
Clojure+ClojureScript WebappsClojure+ClojureScript Webapps
Clojure+ClojureScript Webapps
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
 
Primi passi con Project Tango
Primi passi con Project TangoPrimi passi con Project Tango
Primi passi con Project Tango
 
Effective Modern C++ - Item 35 & 36
Effective Modern C++ - Item 35 & 36Effective Modern C++ - Item 35 & 36
Effective Modern C++ - Item 35 & 36
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
The Ring programming language version 1.6 book - Part 25 of 189
The Ring programming language version 1.6 book - Part 25 of 189The Ring programming language version 1.6 book - Part 25 of 189
The Ring programming language version 1.6 book - Part 25 of 189
 

En vedette (6)

El maltrato infantil en el caquet normal superior
El maltrato infantil en el caquet normal superiorEl maltrato infantil en el caquet normal superior
El maltrato infantil en el caquet normal superior
 
Maltrato infantil
Maltrato infantilMaltrato infantil
Maltrato infantil
 
Plan de prevencion primaria del abuso y del maltrato infantil
Plan de prevencion primaria del abuso y del maltrato infantilPlan de prevencion primaria del abuso y del maltrato infantil
Plan de prevencion primaria del abuso y del maltrato infantil
 
Maltrato Infantil: difinición, causa, factores de riesgo, caracterización de ...
Maltrato Infantil: difinición, causa, factores de riesgo, caracterización de ...Maltrato Infantil: difinición, causa, factores de riesgo, caracterización de ...
Maltrato Infantil: difinición, causa, factores de riesgo, caracterización de ...
 
Maltrato Infantil Y Psquiatria Forense
Maltrato Infantil Y Psquiatria ForenseMaltrato Infantil Y Psquiatria Forense
Maltrato Infantil Y Psquiatria Forense
 
Exposicion Maltrato Infantil
Exposicion Maltrato InfantilExposicion Maltrato Infantil
Exposicion Maltrato Infantil
 

Similaire à Promise of an API

オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)
Takayuki Goto
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
priestmanmable
 
how to reuse code
how to reuse codehow to reuse code
how to reuse code
jleed1
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
Eelco Visser
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
ujihisa
 
How do you stop infinite loop Because I believe that it is making a.pdf
How do you stop infinite loop Because I believe that it is making a.pdfHow do you stop infinite loop Because I believe that it is making a.pdf
How do you stop infinite loop Because I believe that it is making a.pdf
feelinggift
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 

Similaire à Promise of an API (20)

オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)オープンデータを使ったモバイルアプリ開発(応用編)
オープンデータを使ったモバイルアプリ開発(応用編)
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016Promises are so passé - Tim Perry - Codemotion Milan 2016
Promises are so passé - Tim Perry - Codemotion Milan 2016
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
how to reuse code
how to reuse codehow to reuse code
how to reuse code
 
Go Says WAT?
Go Says WAT?Go Says WAT?
Go Says WAT?
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
Async JavaScript in ES7
Async JavaScript in ES7Async JavaScript in ES7
Async JavaScript in ES7
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Watch out: Observables are here to stay
Watch out: Observables are here to stayWatch out: Observables are here to stay
Watch out: Observables are here to stay
 
TI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class FunctionsTI1220 Lecture 6: First-class Functions
TI1220 Lecture 6: First-class Functions
 
Rustlabs Quick Start
Rustlabs Quick StartRustlabs Quick Start
Rustlabs Quick Start
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)Hacking parse.y (RubyKansai38)
Hacking parse.y (RubyKansai38)
 
Day 1
Day 1Day 1
Day 1
 
How do you stop infinite loop Because I believe that it is making a.pdf
How do you stop infinite loop Because I believe that it is making a.pdfHow do you stop infinite loop Because I believe that it is making a.pdf
How do you stop infinite loop Because I believe that it is making a.pdf
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Gabriele Petronella - FP for front-end development: should you care? - Codemo...
Gabriele Petronella - FP for front-end development: should you care? - Codemo...Gabriele Petronella - FP for front-end development: should you care? - Codemo...
Gabriele Petronella - FP for front-end development: should you care? - Codemo...
 

Plus de Maxim Zaks

Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
Maxim Zaks
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013
Maxim Zaks
 
Diagnose of Agile @ Wooga 04.2013
Diagnose of Agile @ Wooga 04.2013Diagnose of Agile @ Wooga 04.2013
Diagnose of Agile @ Wooga 04.2013
Maxim Zaks
 
Start playing @ mobile.cologne 2013
Start playing @ mobile.cologne 2013Start playing @ mobile.cologne 2013
Start playing @ mobile.cologne 2013
Maxim Zaks
 
Under Cocos2D Tree @mdvecon 2013
Under Cocos2D Tree @mdvecon 2013Under Cocos2D Tree @mdvecon 2013
Under Cocos2D Tree @mdvecon 2013
Maxim Zaks
 
Don&rsquo;t do Agile, be Agile @NSConf 2013
Don&rsquo;t do Agile, be Agile @NSConf 2013Don&rsquo;t do Agile, be Agile @NSConf 2013
Don&rsquo;t do Agile, be Agile @NSConf 2013
Maxim Zaks
 

Plus de Maxim Zaks (20)

Entity Component System - a different approach to game and app development
Entity Component System - a different approach to game and app developmentEntity Component System - a different approach to game and app development
Entity Component System - a different approach to game and app development
 
Nitty Gritty of Data Serialisation
Nitty Gritty of Data SerialisationNitty Gritty of Data Serialisation
Nitty Gritty of Data Serialisation
 
Wind of change
Wind of changeWind of change
Wind of change
 
Data model mal anders
Data model mal andersData model mal anders
Data model mal anders
 
Talk Binary to Me
Talk Binary to MeTalk Binary to Me
Talk Binary to Me
 
Entity Component System - for App developers
Entity Component System - for App developersEntity Component System - for App developers
Entity Component System - for App developers
 
Beyond JSON - An Introduction to FlatBuffers
Beyond JSON - An Introduction to FlatBuffersBeyond JSON - An Introduction to FlatBuffers
Beyond JSON - An Introduction to FlatBuffers
 
Beyond JSON @ Mobile.Warsaw
Beyond JSON @ Mobile.WarsawBeyond JSON @ Mobile.Warsaw
Beyond JSON @ Mobile.Warsaw
 
Beyond JSON @ dot swift 2016
Beyond JSON @ dot swift 2016Beyond JSON @ dot swift 2016
Beyond JSON @ dot swift 2016
 
Beyond JSON with FlatBuffers
Beyond JSON with FlatBuffersBeyond JSON with FlatBuffers
Beyond JSON with FlatBuffers
 
Basics of Computer Science
Basics of Computer ScienceBasics of Computer Science
Basics of Computer Science
 
Entity system architecture with Unity @Unite Europe 2015
Entity system architecture with Unity @Unite Europe 2015 Entity system architecture with Unity @Unite Europe 2015
Entity system architecture with Unity @Unite Europe 2015
 
UIKonf App & Data Driven Design @swift.berlin
UIKonf App & Data Driven Design @swift.berlinUIKonf App & Data Driven Design @swift.berlin
UIKonf App & Data Driven Design @swift.berlin
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
 
Currying in Swift
Currying in SwiftCurrying in Swift
Currying in Swift
 
96% macoun 2013
96% macoun 201396% macoun 2013
96% macoun 2013
 
Diagnose of Agile @ Wooga 04.2013
Diagnose of Agile @ Wooga 04.2013Diagnose of Agile @ Wooga 04.2013
Diagnose of Agile @ Wooga 04.2013
 
Start playing @ mobile.cologne 2013
Start playing @ mobile.cologne 2013Start playing @ mobile.cologne 2013
Start playing @ mobile.cologne 2013
 
Under Cocos2D Tree @mdvecon 2013
Under Cocos2D Tree @mdvecon 2013Under Cocos2D Tree @mdvecon 2013
Under Cocos2D Tree @mdvecon 2013
 
Don&rsquo;t do Agile, be Agile @NSConf 2013
Don&rsquo;t do Agile, be Agile @NSConf 2013Don&rsquo;t do Agile, be Agile @NSConf 2013
Don&rsquo;t do Agile, be Agile @NSConf 2013
 

Dernier

FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
dollysharma2066
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ssuser89054b
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
dharasingh5698
 
AKTU Computer Networks notes --- Unit 3.pdf
AKTU Computer Networks notes ---  Unit 3.pdfAKTU Computer Networks notes ---  Unit 3.pdf
AKTU Computer Networks notes --- Unit 3.pdf
ankushspencer015
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Dernier (20)

FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Mahipalpur Delhi Contact Us 8377877756
 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.ppt
 
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
 
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank  Design by Working Stress - IS Method.pdfIntze Overhead Water Tank  Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
 
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort ServiceCall Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
Call Girls in Ramesh Nagar Delhi 💯 Call Us 🔝9953056974 🔝 Escort Service
 
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Palanpur 7001035870 Whatsapp Number, 24/07 Booking
 
AKTU Computer Networks notes --- Unit 3.pdf
AKTU Computer Networks notes ---  Unit 3.pdfAKTU Computer Networks notes ---  Unit 3.pdf
AKTU Computer Networks notes --- Unit 3.pdf
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELLPVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
PVC VS. FIBERGLASS (FRP) GRAVITY SEWER - UNI BELL
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 
Call for Papers - International Journal of Intelligent Systems and Applicatio...
Call for Papers - International Journal of Intelligent Systems and Applicatio...Call for Papers - International Journal of Intelligent Systems and Applicatio...
Call for Papers - International Journal of Intelligent Systems and Applicatio...
 

Promise of an API

  • 1. Promise of an API Maxim Zaks (@iceX33) CocoaHeads Berlin
  • 2. Agenda — Consume a promise — Produce a promise — Swift
  • 5. - (NSNumber*)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2; - (NSNumber*)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 withError:(NSError**)error; - (void)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 withBlock:(void (^)(NSNumber *sum, NSError *error))block;
  • 6. - (NSNumber*)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2; - (NSNumber*)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 withError:(NSError**)error; - (void)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 withBlock:(void (^)(NSNumber *sum, NSError *error))block; - (void)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 success:(void (^)(NSNumber *sum))success failure:(void (^)(NSError *error))failur;
  • 7. And now with a real promise! - (OMPromise*)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2;
  • 8. What is a promise (OMPromise)? It's just an object
  • 9. It has state — Unfulfilled — Fulfilled — Failed
  • 10. It has other properties — result — error — progress*
  • 11. It has methods - (OMPromise *)fulfilled:(void (^)(id result))fulfilHandler; - (OMPromise *)failed:(void (^)(NSError *error))failHandler; - (OMPromise *)progressed:(void (^)(float progress))progressHandler;
  • 12. It lets you call handlers on a custom queue - (OMPromise *)fulfilled:(void (^)(id result))fulfilHandler on:(dispatch_queue_t)queue; - (OMPromise *)failed:(void (^)(NSError *error))failHandler on:(dispatch_queue_t)queue; - (OMPromise *)progressed:(void (^)(float progress))progressHandler on:(dispatch_queue_t)queue;
  • 13. So let's see it in action
  • 14. OMPromise *sum = [calc addFirstNumber:@3 toSecondNumber:@2]; [[sum fulfilled:^(id result){ NSLog(@"Sum: %@", result); }] failed:^(NSError *error){ NSLog(@"Failed to calculate because of: %@", error); }];
  • 15. Concatenation sum1 = 3 + 2 sum2 = sum1 + 2 sum3 = sum1 + 3
  • 16. Concatenation OMPromise *sum1 = [calc addFirstNumber:@3 toSecondNumber:@2]; OMPromise *sum2 = [sum1 than:^(NSNumber *n1){ return [calc addFirstNumber:n1 toSecondNumber:@2]; }]; OMPromise *sum3 = [sum1 than:^(NSNumber *n1){ return [calc addFirstNumber:n1 toSecondNumber:@3]; }]; [[[OMPromise all:@[sum1, sum2, sum3]] fulfilled:^(NSArray *results){ NSLog(@"Sum1: %@, Sum2: %@, Sum3: %@", results[0], results[1], results[2]); } on:dispatch_get_main_queue()] failed:^(NSError *error){ NSLog(@"Failed to calculate because of: %@", error); } on:dispatch_get_main_queue()];
  • 17.
  • 18. Deep chaining OMPromise *sum = [OMPromise chain:[ ^(NSNumber *n1){ return [calc addFirstNumber:@2 toSecondNumber:@3]; }, ^(NSNumber *n1){ return [calc addFirstNumber:n1 toSecondNumber:@3]; }, ^(NSNumber *n1){ return [calc addFirstNumber:n1 toSecondNumber:@2]; } ] initial:nil];
  • 19. Recovering from failed promise OMPromise *sum1 = [calc addFirstNumber:@3 toSecondNumber:@2]; OMPromise *rescuedSum = [sum1 rescue:^(NSError *error){ NSLog(@"Shit happens! %@", error); return @0; }];
  • 20. Recap 1/3 @interface OMPromise : NSObject @property(assign, readonly, nonatomic) OMPromiseState state; @property(readonly, nonatomic) id result; @property(readonly, nonatomic) NSError *error; @property(assign, readonly, nonatomic) float progress;
  • 21. Recap 2/3 - (OMPromise *)fulfilled:(void (^)(id result))fulfilHandler; - (OMPromise *)failed:(void (^)(NSError *error))failHandler; - (OMPromise *)progressed:(void (^)(float progress))progressHandler; - (OMPromise *)then:(id (^)(id result))thenHandler; - (OMPromise *)rescue:(id (^)(NSError *error))rescueHandler;
  • 22. Recap 3/3 + (OMPromise *)chain:(NSArray *)thenHandlers initial:(id)result; + (OMPromise *)any:(NSArray *)promises; + (OMPromise *)all:(NSArray *)promises;
  • 23. Now what's about creating a promise?
  • 24. Convenience methods on OMPromise + (OMPromise *)promiseWithResult:(id)result; + (OMPromise *)promiseWithResult:(id)result after:(NSTimeInterval)delay; + (OMPromise *)promiseWithError:(NSError *)error; + (OMPromise *)promiseWithTask:(id (^)())task;
  • 25. Example for success - (OMPromise *)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 { return [OMPromise promiseWithTask:^{ return @([n1 intValue] + [n2 intValue]) }]; }
  • 26. Example for error - (OMPromise *)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 { return [OMPromise promiseWithTask:^{ return [NSError new]; }]; }
  • 27. And what is the non convenient way?
  • 28. Defered object @interface OMDeferred : OMPromise + (OMDeferred *)deferred; - (OMPromise *)promise; - (void)fulfil:(id)result; - (void)fail:(NSError *)error; - (void)progress:(float)progress; @end
  • 29. Example - (OMPromise *)addFirstNumber:(NSNumber*)number1 toSecondNumber:(NSNumber*)number2 { OMDeferred *deferred = [OMDeferred deferred]; dispatch_async(dispatch_get_global_queue(0, 0), ^ { NSError *error = nil; NSNumber *sum = [self addFirstNumber:number1 toSecondNumber:number2 withError:&error]; if(error){ [deferred fail:error]; } else { [deferred fulfill:sum]; } }); return deferred.promise; }
  • 30. Recap — Promise is an immutable data structure — Deferred is a subclass of Promise which makes it mutable
  • 31. To add up confusion I implemented promises in Swift
  • 32. First attempt was just to port it
  • 33. Using Enums for state representation feels right enum PromiseState{ case Unfulfilled case Fulfilled case Failed }
  • 34. I need inheritance so let's use classes
  • 35. Using constants as read only property is not a good idea as you have to set them directly in the initializer class Promise<T> { let state : PromiseState let result : T let error : NSError }
  • 36. Switching to var makes it work but Promise is not immutable any more class Promise<T> { var state : PromiseState var result : T? var error : NSError? init(){ state = .Unfulfilled } func fulfill(value : T){ result = value state = .Fulfilled } }
  • 37. Trying to make a read only property class Promise<T> { var state : PromiseState var result : T? { get { return self.result } } var error : NSError? init(){ state = .Unfulfilled } }
  • 38. Sadly this was an infinite loop — There are no Read-Only properties in Swift — Only Read-Only Computed Properties
  • 39. Schock number 2 — There are no ivars in Swift — And no visibility constrains (but they promised to introduced those)
  • 40. After initial shock pass, I decided to go functional
  • 41. func future<T>(execution : ()->FutureResult<T>)(handler: FutureHandler<T>) { var result : FutureResult<T>? var done = false dispatch_async(dispatch_get_global_queue(0, 0)) { result = execution() done = true } dispatch_async(dispatch_get_global_queue(0, 0)) { while !done {} dispatch_async(dispatch_get_main_queue()) { switch handler { case .FulFilled(let fulfilled): switch result! { case .Result(let value): fulfilled(value()) case .Error : println("can't process error") } case .Failed(let failed): switch result! { case .Result: println("can't process result") case .Error(let error) : failed(error()) } } } } }
  • 42. Main concept = currying func add(n1:Int)(n2:Int) -> Int { return n1 + n2 } let increaseByTwo = add(2) let sum = increaseByTwo(3)
  • 43. Using enums with Associated Values enum FutureHandler<T>{ case FulFilled((T)->()) case Failed((NSError)->()) } enum FutureResult<T>{ case Result(@auto_closure ()->T) case Error(@auto_closure ()->NSError) }
  • 44. Here is how you can use it: var f = future { FutureResult.Result(2 + 3) } f (handler: FutureHandler.FulFilled { result in println("Promise fulfilled : (result)") })
  • 45. It's not a beauty but it works
  • 46. However you can't concatenate futures in this implementation — typealias F = (FutureHandler<Int>) -> F
  • 47. For the tough ones, who survived this talk: — https://github.com/b52/OMPromises — https://github.com/mzaks/siwft-future