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

Intro to Functional Reactive Programming (Droidcon MTL 2015)

Juan Gomez
April 12, 2015

Intro to Functional Reactive Programming (Droidcon MTL 2015)

This talk will be an introduction to the ideas behind functional reactive programming and how you can move away from traditional synchronous state management with variables to asynchronous streams of data instead. You will learn how Rx (Reactive Extensions) Observables simplify concurrent code and let you write asynchronous, message based Android apps, in ways that are more elegant and a bit less error prone than traditional Android mechanisms.

We will also take a look at some Higher-order functions such as map(), flatmap(), filter() and reduce() that enable you to write simple, expressive and concise code to process Observables and solve problems in many common Android scenarios. These powerful yet easy to use abstractions will let you write asynchronous code in a more straightforward, declarative fashion; making your life as an Android developer a lot easier.

Juan Gomez

April 12, 2015
Tweet

More Decks by Juan Gomez

Other Decks in Technology

Transcript

  1. Functional Reactive
    Programming
    Juan Gomez

    View Slide

  2. Intro
    Who am I?
    • Mobile Engineer at Netflix
    • Previously at Eventbrite and OneLouder Apps
    • Android & Python Developer

    View Slide

  3. Agenda
    • Brief introduction to Rx and why we want to use it.
    • Observables and useful operators to transform
    Observables.
    • Brief introduction to RxAndroid.

    View Slide

  4. Multithreading is hard!
    This is a lesson I seem to learn every few years:
    multithreading is hard.

    Once you think you now understand it and are an
    expert, you are heading soon to another painful
    lesson that multithreading is hard.
    - Dianne Hackborn
    April 2012

    View Slide

  5. What Is Functional Reactive
    Programming?
    • A style of programming
    based on two key ideas:
    continuous time-varying
    behaviors, and event-based
    reactivity.
    • Popularized by Erik Meijer
    when he created the Rx
    library for .NET while at
    Microsoft.

    View Slide

  6. Functional Reactive
    Programming in Java
    aObservable.map(x -> x*x) //Square
    .reduce((a, b) -> a+b) //Sum
    .subscribe(x -> println(x)); //Show

    View Slide

  7. Why Functional Reactive
    Programming
    • Writing concurrent programs correctly is difficult.
    • You can transform & compose asynchronous
    operations.
    • High-level abstractions
    • Standard error handling

    View Slide

  8. Rx Family
    • C#: Rx.NET
    • JavaScript: RxJS
    • RxJava (Java, Scala, Groovy, Clojure, Kotlin)
    • Ruby: Rx.rb
    • Python: RxPY
    • More at: http://reactivex.io/

    View Slide

  9. RxJava
    • It’s a JVM implementation of Reactive Extensions
    • Extends Observer pattern to support data/event
    and compose operators in abstract.
    • Started at Netflix
    • Supports Java 6+ & Android 2.3+
    • Java 8 lambda support

    View Slide

  10. Observables
    event Iterable (pull) Observable (push)
    retrieve data T next() onNext(T)
    discover error throws Exception onError(Exception)
    complete !hasNext() onCompleted()
    It’s like the GoF Observer++

    View Slide

  11. Push vs Pull

    View Slide

  12. Observer Pattern on Android

    View Slide

  13. Android using RFP

    View Slide

  14. View Slide

  15. RxJava on Java 7
    aObservable.filter(new Func1() {
    public Boolean call(Integer n) {
    return n % 2 == 0;
    }
    })
    .map(new Func1() {
    public Integer call(Integer n) {
    return n * n;
    }
    })
    .subscribe(new Action1() {
    public void call(Integer n) {
    System.out.println(n);
    }
    });

    View Slide

  16. Retrolambda
    Retrolambda lets you take advantage of Java 8
    features like lambda expressions and method
    references on Java 7 or lower.
    • Retrolambda
    • https://github.com/orfjackal/retrolambda
    • Gradle plugin
    • https://github.com/evant/gradle-retrolambda

    View Slide

  17. RxJava using Retrolambda
    aObservable.filter(n -> n % 2 == 0)
    .map(n -> n * n)
    .subscribe(System.out::println);

    View Slide

  18. Creating an Observable

    View Slide

  19. Creating an Observable
    List aList = ...;
    ob = Observable.create(subscriber -> {
    try {
    for (String s : aList) {
    if (subscriber.isUnsubscribed())
    return;
    subscriber.onNext(s);
    }
    subscriber.onCompleted();
    } catch (Exception e) {
    subscriber.onError(e);
    }
    });

    View Slide

  20. Creating an Observable
    List aList = ...;
    Observable ob = Observable.from(aList);

    View Slide

  21. Creating an Observable
    Observable> ob = Observable.just(aList);
    Observable ob2 = Observable.just("Some String");

    View Slide

  22. Creating an Observable
    • repeat( )
    • range( )
    • interval( )
    • timer( )
    • empty( )
    • error( )
    • More at: https://github.com/ReactiveX/RxJava/wiki/Creating-
    Observables

    View Slide

  23. Transforming Observables

    View Slide

  24. Transforming Observables
    Observable.range(0, 5)
    .map(x -> toBinaryString(x*x))
    .subscribe(s -> println(s),
    err -> err.printStackTrace(),
    () -> println("done"));
    0
    1
    100
    1001
    10000
    done

    View Slide

  25. Transforming Observables

    View Slide

  26. Transforming Observables
    1
    2
    2
    3
    3
    3
    Observable.range(1, 3)
    .flatMap(x -> Observable.just(x).repeat(x))
    .subscribe(System.out::println);

    View Slide

  27. Filtering Observables

    View Slide

  28. Filtering Observables
    0
    2
    4
    6
    8
    Observable.range(0, 10)
    .filter(x -> (x % 2) == 0)
    .subscribe(System.out::println);

    View Slide

  29. Filtering Observables
    • distinct( )
    • first( )
    • take( )
    • skip( )
    • elementAt( )
    • sample( )
    • more...
    • More at: https://github.com/ReactiveX/RxJava/wiki/Filtering-Observables

    View Slide

  30. Aggregate Operators

    View Slide

  31. Aggregate Operators
    3628800
    Observable.range(1, 10)
    .reduce((a, b) -> a*b)
    .subscribe(System.out::println);

    View Slide

  32. Combining Observables

    View Slide

  33. Combining Observables
    a_A
    b_B
    c_C
    Observable lower =
    Observable.from(new String[]{"a", "b", "c"});
    Observable upper =
    Observable.from(new String[]{"A", "B", "C"});
    Observable.zip(lower, upper, Pair::create)
    .map(pair -> pair.first +"_" +pair.second)
    .subscribe(System.out::println);

    View Slide

  34. Threading
    • observeOn
    • specify on which Scheduler a Subscriber should
    observe the Observable
    • subscribeOn
    • specify which Scheduler an Observable should use
    when its subscription is invoked
    • https://github.com/ReactiveX/RxJava/wiki/
    Scheduler

    View Slide

  35. Backpressure
    • Backpressure is the situation in which an
    Observable is emitting items more rapidly than an
    operator or subscriber can consume them.
    • RxJava offers a variety of strategies like throttling
    with which you can exercise flow control in order to
    alleviate the problems caused by backpressure.
    • https://github.com/ReactiveX/RxJava/wiki/Backpressure

    View Slide

  36. Hot and Cold Observables
    • A “cold” Observable waits to start emitting items
    until an observer subscribes, and so an observer
    can “observe” the whole sequence.
    • A “hot” Observable may begins emitting items as
    soon as it is created.

    View Slide

  37. RxAndroid
    • Android specific bindings for RxJava.
    • https://github.com/ReactiveX/RxAndroid
    • Scheduler on main UI thread or a given Android Handler thread.
    • AndroidSchedulers
    • HandlerThreadScheduler
    • Reactive components for common Android use cases and UI widgets
    • AndroidObservable
    • ViewObservable

    View Slide

  38. Android Example
    /* API */
    Observable getFromServer(String key);
    Observable getFromDB(String key);
    /* Code */
    ViewObservable.clicks(btnClick)
    .map(x -> "myid")
    .observeOn(Schedulers.io())
    .flatMap(this::getFromDB)
    .flatMap(this::getFromServer)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(x -> Toast.makeText(context, x,
    LENGTH_LONG).show());

    View Slide

  39. Summary
    • Embrace Reactive and Functional Thinking
    • Manipulating Streams of Data simplifies who
    we think (and build) our programs.
    • RxJava is a powerful tool to improve your
    Android Code

    View Slide

  40. Useful links
    • https://github.com/ReactiveX/RxJava/wiki/
    • https://github.com/ReactiveX/RxAndroid
    • http://reactivex.io/documentation/operators.html
    • http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
    • https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

    View Slide

  41. Thank You!
    Twitter: @_juandg
    Email: [email protected]flix.com
    Lanyrd: lanyrd.com/profile/juandg/

    View Slide