Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Reactive Programming in the Mobile World

Edward Dale
November 27, 2013

Functional Reactive Programming in the Mobile World

Edward Dale

November 27, 2013
Tweet

More Decks by Edward Dale

Other Decks in Programming

Transcript

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

    View Slide

  2. Agenda
    • Theory
    • The mobile world
    • Functional Reactive
    Programming (FRP)
    • Practice
    • ReactiveExtensions (RX)
    • ReactiveCocoa
    • RxJava
    !2
    http://knowyourmeme.com/memes/business-cat

    View Slide

  3. The Mobile World
    • (or maybe the desktop world)
    • Event-based (onTouch,
    onLongClick, network
    connection lost, etc)
    • Concurrent
    • Messy
    !3

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  8. Observer
    1 //Provides a mechanism for receiving push-based notifications.
    2 public interface IObserver {
    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

    View Slide

  9. Marble Diagrams
    !8
    https://raw.github.com/wiki/Netflix/RxJava/images/rx-operators/legend.png

    View Slide

  10. ReactiveCocoa
    • Implementation of Reactive
    Extensions for Objective C
    • Originally by GitHub
    !9

    View Slide

  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

    View Slide

  12. 1 - (RACSignal *) savedPages {
    2 return [[[RACSignal createSignal:^RACDisposable *(id 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

    View Slide

  13. RxJava
    • Implementation of Reactive
    Extensions for Java
    • Originally by Netflix
    !12

    View Slide

  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 bodyText = Events.text(bodyEdit);
    9
    10 // send button is only enabled when we have some body content
    11 bodyText.map(new Func1() {
    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

    View Slide

  15. RxJava Example 2
    1 public Observable getWeatherData(final String city) {
    2 return Observable.create(new Observable.OnSubscribeFunc() {
    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/

    View Slide

  16. Questions?
    Edward Dale
    @scompt

    View Slide