Pro Yearly is on sale from $80 to $50! »

Functional Reactive Programming in the Mobile World

730df0227780e818df8ce1e19c9a6c48?s=47 Edward Dale
November 27, 2013

Functional Reactive Programming in the Mobile World

730df0227780e818df8ce1e19c9a6c48?s=128

Edward Dale

November 27, 2013
Tweet

Transcript

  1. Functional Reactive Programming in the Mobile World ! Edward Dale

    @scompt
  2. Agenda • Theory • The mobile world • Functional Reactive

    Programming (FRP) • Practice • ReactiveExtensions (RX) • ReactiveCocoa • RxJava !2 http://knowyourmeme.com/memes/business-cat
  3. The Mobile World • (or maybe the desktop world) •

    Event-based (onTouch, onLongClick, network connection lost, etc) • Concurrent • Messy !3
  4. Lots of solutions to concurrency complexity • Grand Central Dispatch

    • NSOperationQueue • Loader • AsyncTask • ExecutorService • Thread !4 http://www.flickr.com/photos/30630175@N07/2950272850
  5. Lots of solutions to concurrency complexity • Grand Central Dispatch

    • NSOperationQueue • Loader • AsyncTask • ExecutorService • Thread Still using! imperative! programming !4 http://www.flickr.com/photos/30630175@N07/2950272850
  6. Functional Reactive Programming (FRP) • Functional • Emphasize functions as

    the building blocks of a program • Avoid mutable data and side effects • x′ = f(x) • Reactive • Emphasize data flow and propagation of change • Similar to Observer pattern • a := b + c λ !5
  7. FRP in Practice • Reactive Extensions (Rx) • from Microsoft

    • Rx = Observables + Operators + Schedulers • Observables represent asynchronous data streams • Operators query 
 asynchronous data streams • Schedulers parameterize
 the concurrency in
 asynchronous data streams !6
  8. Observer 1 //Provides a mechanism for receiving push-based notifications. 2

    public interface IObserver<in T> { 3 //Provides the observer with new data. 4 void OnNext(T value); 5 6 // Notifies the observer that the provider has 7 // experienced an error condition. 8 void OnError(Exception error); 9 10 // Notifies the observer that the provider has 11 // finished sending push-based notifications. 12 void OnCompleted(); 13 } !7
  9. Marble Diagrams !8 https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/legend.png

  10. ReactiveCocoa • Implementation of Reactive Extensions for Objective C •

    Originally by GitHub !9
  11. ReactiveCocoa Example 1 1 - (id)init 2 { 3 self

    = [super initWithFrame:CGRectZero]; 4 if (self) { 5 // Build objects... 6 RAC(backButton, enabled) = RACObserve(self, backEnabled); 7 RAC(forwardButton, enabled) = RACObserve(self, forwardEnabled); 8 RAC(titleLabel, text) = RACObserve(self, title); 9 10 RACSignal *loadingSignal = RACObserve(self, loading); 11 RAC(refreshButton, hidden) = loadingSignal; 12 RAC(stopButton, hidden) = [loadingSignal map:^id(NSNumber *enabled) { 13 return [NSNumber numberWithBool:![enabled boolValue]]; 14 }]; 15 } 16 return self; 17 } !10
  12. 1 - (RACSignal *) savedPages { 2 return [[[RACSignal createSignal:^RACDisposable

    *(id<RACSubscriber> subsc) { 3 NSURLSessionDataTask *op = 4 5 [self GET:@"saved_pages" 6 parameters:nil 7 success:^(NSURLSessionDataTask *operation, NSXMLParser *parser) { 8 GVSavedPagesParserDelegate *parDel = 9 [GVSavedPagesParserDelegate new]; 10 parser.delegate = parDel; 11 if([parser parse]) { 12 [subsc sendNext:RACTuplePack(parDel.savedPages, 13 parDel.homepage)]; 14 [subsc sendCompleted]; 15 } else { 16 [subsc sendError:parser.parserError]; 17 } 18 } 19 failure:^(NSURLSessionDataTask *operation, NSError *error) { 20 [subsc sendError:error]; 21 }]; 22 23 return [RACDisposable disposableWithBlock:^{ 24 [op cancel]; 25 }]; 26 }] replayLazily] subscribeOn:[RACScheduler scheduler]]; 27 } ReactiveCocoa Example 2 WIP !11
  13. RxJava • Implementation of Reactive Extensions for Java • Originally

    by Netflix !12
  14. RxJava Example 1 1 @Override 2 public void onCreate(Bundle savedInstanceState)

    { 3 4 // ... 5 6 final Button sendButton = (Button) findViewById(R.id.send); 7 final EditText bodyEdit = (EditText) findViewById(R.id.body); 8 final Observable<String> bodyText = Events.text(bodyEdit); 9 10 // send button is only enabled when we have some body content 11 bodyText.map(new Func1<String, Boolean>() { 12 @Override 13 public Boolean call(String text) { 14 return !text.trim().equals(""); 15 } 16 }).subscribe(Properties.enabledFrom(sendButton)); 17 } !13 https://github.com/andrewhr/rxjava-android-example/blob/master/app/src/main/java/com/example/rx/ComposeMessageActivity.java
  15. RxJava Example 2 1 public Observable<WeatherData> getWeatherData(final String city) {

    2 return Observable.create(new Observable.OnSubscribeFunc<WeatherData>() { 3 @Override 4 public Subscription onSubscribe(Observer<? super WeatherData> obs) { 5 try { 6 obs.onNext(apiManager.getWeather(city, "metric")); 7 obs.onCompleted(); 8 } catch (Exception e) { 9 obs.onError(e); 10 } 11 12 return Subscriptions.empty(); 13 } 14 }).subscribeOn(Schedulers.threadPoolForIO()); 15 } !14 http://howrobotswork.wordpress.com/2013/10/28/using-rxjava-in-android/
  16. Questions? Edward Dale @scompt