+ ^ | | @giorgionatili +-------------------------------------+--------------+ FRP + Kotlin A journey into new programming paradigms and magical operators
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> About Me / : / :' .. / :' ( , ' |( ' ( ` .---. ` .-..-. ( _.._.--. `. ' '._`-._..-'``__ `-. '. ..7 '. ``` /``` `'. `-.-~-.`-/ .-.:>. __. '. | ( `' ( ( . . ) `'-._ `'(__. : .7 (_. ( : .' , '- __--': . . `' / ,: ,/ /__. . . '--'` `--' `' / | : /| / | |` | / | : ( .' .'| '. ' ( / | : '. ( ( )./- (` ,./.-''-:. + Engineering Manager at Akamai
 (NG2 on desktop and mobile) + VP of Engineering at Sync Think
 (Android, VR and Python) + Founder of Mobile Tea 
 (www.meetup.com/pro/mobiletea) + Leader of the Boston Twitter UG + Organizer of DroidCon Boston
 (www.droidcon-boston.com)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Agenda + Functional Reactive Programming + Kotlin in a nutshell + RxKotlin: FRP with Android + Kotlin and multithreading
+ ^ | | @giorgionatili +-------------------------------------+--------------+ Functional Reactive Programming
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> What the hell is FRP + FRP is a programming paradigm + It focuses on reacting to streams of changes (data and events) + It favors function composition, avoidance of global state and side effects
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Programming Paradigm + Humans do not think like computer so we add abstractions + FRP is an abstraction just like imperative programming idioms are abstractions for binary instructions + FRP is all about capturing evolving values (aka Observer pattern on steroids 🚀)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Streams + a, b, c, d are emitted values + X is an error + | is the 'completed' signal + ---> is the timeline + --a---b-c---d---X---|->
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Functions Composition + The values returned by any operator are chain-able (functional magic 😎) + The original input is immutable val strings = listOf("one", "two", "treee", "a", "four") val filtered = strings.filter { it.length >= 3 } .map { it.toUpperCase() } println(filtered) // ONE, TWO, THREE, FOUR
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Disclaimer RxJava and RxKotlin are not pure FRP, in fact, FRP involves continuos time whereas the Reactive Extensions only deal with discrete event over time. Anyway, the implementation and the chain-able operators make RxJava and RxKotlin a good enough solution for Android apps.
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Installation compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.0.1'
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Observable<T> + An Observable represents a flowing stream of values + UI events + Data processed in background + The most similar abstraction is Iterable<T>
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Push vs Pull + Observable is push based, it decides when to emit values + Iterable is pull based, it sits until the some ask for the next() value
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Push vs Pull // Java Range range = new Range(1, 10); Iterator<Integer> it = range.iterator(); while(it.hasNext()) { int cur = it.next(); System.out.println(cur); } // RxJava Observable.range(1, 10).subscribe({ println(it); });
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Observable Specs Every Observable can emit an arbitrary number of values optionally followed by completion or error (but not both) interface Observer < T > { void onNext( T t) // Data void onError( Throwable t) // Error void onCompleted() // Stream completion }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Create an Observable Observable are lazy, creation doesn’t trigger any action Observable < Tweet > tweets = Observable.create( s -> { getDataFromServerWithCallback( args, data -> { try { s.onNext( data ); s.onCompleted(); } catch (Throwable t) { s.onError(t); } }); });
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Subscribe to an Observable Subscription activates the Observable Observable < Tweet > tweets = // ... tweets.subscribe( (Tweet tweet) -> {
 println( tweet ); },(Throwable t) -> { 
 t.printStackTrace(); });
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Cold vs Hot Observables + A cold Observable is entirely lazy + Hot Observables might already be emitting events no matter how many Subscribers they have + Hot Observables occur when we have absolutely no control over the source of events (aka taps)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> FlatMap Transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable // Returns a List of websites based on text search Observable<List<String>> query(String text); query("Hello, world!") .flatMap(urls -> Observable.from(urls)) .subscribe(url -> System.out.println(url));
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Scan Apply a function to each item emitted by an Observable, sequentially, and emit each successive value 
 +----1---2------3------4--------5--------------> 
 scan((x, y) -> (x + y)); +----1---3------6------10-------15------------->
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> GroupBy Observable.from(NumbersGenerator.getList(1000)) .groupBy((i) -> 0 == (int)i % 2 ? "EVEN" : "ODD") .subscribe((group) -> { println("Key " + ((GroupedObservable)group).getKey()); ((GroupedObservable)group).subscribe((x) ->
 println(((GroupedObservable)group).getKey() + ": " + x)); }); Divide an Observable into a set of Observables that each emit a different group of items from the original Observable, organized by key 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Distinct The Distinct operator filters an Observable by only allowing items through that have not already been emitted Observable < Integer > randomInts = Observable.create( subscriber -> { Random random = new Random(); while (! subscriber.isUnsubscribed()) { subscriber.onNext( random.nextInt( 1000 )); } }); Observable < Integer > uniqueRandomInts = randomInts .distinct() .take( 10); 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Take Emit only the first n items emitted by an Observable Observable.interval(1, TimeUnit.SECONDS) .map { it.toInt() } .take(20) 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Buffer Creates a new buffer starting with the first emitted item from the source Observable, and every skip items thereafter, fills each buffer with count items +--1----2----3----------4-----5------6-------> 
 buffer(count=2, skip|3) +-----1---2-----------------4-----5--------->
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Debounce Only emit an item from an Observable if a particular timespan has passed without it emitting another item String[] items = {"one", "two", "three", "four", "five"}; Observable.from(items) .debounce(item -> item.equals("one") ? Observable.empty() : Observable.timer(1, TimeUnit.SECONDS)); 😲 😏 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> FRP Use Cases + Processing user (tap, swipe, etc.) and system events (GPS, gyroscope, etc.) + Responding and processing any IO event (asynchronously) + Handling events and data pushed from other sources + Many, many, many others! :)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Handling User Input Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(final Subscriber<? super String> subscriber) { editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after){} @Override public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
 subscriber.onNext(s.toString()); } @Override public void afterTextChanged(final Editable s) { } }); } }) .debounce(1000, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(final String s) { textView.setText("Output : " + s); } }); Create Emit Handle stream Subscribe
+ ^ | | @giorgionatili +-------------------------------------+--------------+ Kotlin in a Nutshell
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Why Kotlin + Data classes + Inferred datatypes + Nullable types + Arguments default value + Lambda expression and "elvis" operator + Extension functions
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Install the Plugin
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Kotlin and the JVM * Interoperable 100%
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Nullable Types Nothing can be null in Kotlin until is not specified val a : String = null // won't compile! var b : Int // neither! must be initialized val ok : String? = null // OK :)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Data Classes // Java public class User { private final String nickname; public User(String nickname) { this.nickname = nickname; } public String getNickname() { return nickname; } } // Kotlin class User (val nickname: String)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Custom Getters class SubscribingUser(val email: String) { val nickname: String get() { return email.substringBefore("@") } } 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Inferred Datatypes The data type can be inferred by the context or by the first assignment class LengthCounter { var counter = 0 private set fun addWord(word: String) { counter += word.length } }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Inline Functions and Default Values + Functions can be declared outside of a class and imported in others + Arguments can have default values reducing the number of methods overloads
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Elvis Operator This is the name used for this operator ?:, you can use it to give an alternative value in case the object is null try { // code... } catch (e: Throwable) { Log.e("TAG", e.message ?: "Error message") }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Lambas + Small chunks of code that can be passed to other functions + The ability to treat functions as values is part of the functional programming paradigm val people = listOf(Person("Alice", 29), 
 Person("Bob", 31)) println(people.maxBy { it.age }) 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> The "apply" Function + The apply function allows to execute multiple operations on the same object + The apply function converts its first argument into a receiver of the lambda passed as a second argument fun alphabet() = StringBuilder().apply { for (letter in 'A'..'Z') { append(letter) } append("nNow I know the alphabet!") }.toString() 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> The "with" Function The with function works like the apply one and returns the object to which is applied fun alphabet() = with(StringBuilder()) { for (letter in 'A'..'Z') { append(letter) } toString() } 😏
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> High-Order Functions A higher-order function is a function that takes functions as parameters, or returns a function fun <T> lock(lock: Lock, body: () -> T): T { lock.lock() try { return body() } finally { lock.unlock() } }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Extension Functions + Functions that add a new behavior to a class + It’s a way to extend classes which lack some useful functions fun String.lastChar(): Char = this.get(this.length - 1)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Java to Kotlin + On the main menu, point to Code menu. + Choose Convert Java File to Kotlin File
+ ^ | | @giorgionatili +-------------------------------------+--------------+ Recap
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> What We Got so Far + FRP is a programming paradigm + RxJava is a library for composing asynchronous and event-based programs using observable sequences for the Java VM + Kotlin is a statically-typed programming language that runs on the Java Virtual Machine
+ ^ | | @giorgionatili +-------------------------------------+--------------+ RxKotlin: FRP with Android
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Concise + The words extends and implement were replaced by a colon : + Methods are defined with the fun keyword, the return type is optional class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Click Listeners The lack of lambdas in Java 7 is the reason why listeners and callbacks are so awful to write with Kotlin myButton.setOnClickListener { navigateToDetail() }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Toasts and Snacks fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){ Toast.makeText(this, message, duration).show() } toast("Hello Kotlin!") fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG, f: Snackbar.() -> Unit) { val snack = Snackbar.make(this, message, length) snack.f() snack.show() } view.snack("This is my snack")
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Composability view.snack("Snack message") { action("Action") { toast("Action clicked") } } fun Snackbar.action(action: String, color: Int? = null, listener: (View) -> Unit) { setAction(action, listener) color?.let { setActionTextColor(color) } }
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Android Extensions + By adding a specific import, the plugin will be able to create a set of properties for an activity, a fragment, or even a view + The name of the properties will be the ones defined in the XML you are importing import kotlinx.android.synthetic.main.activity_detail.*
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Inflate fun ViewGroup.inflate(layoutId: Int): View { return LayoutInflater.from(context) .inflate(layoutId, this, false) } val view = container?.inflate(R.layout.news_fragment)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> RxBindings import kotlinx.android.synthetic.main.activity_detail.editText RxTextView.afterTextChangeEvents(editText) .debounce(1000, TimeUnit.MILLISECONDS) .subscribe { tvChangeEvent -> textView.text = "Output : " + tvChangeEvent.view().text }
+ ^ | | @giorgionatili +-------------------------------------+--------------+ Multithreading Made Simple
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> RxJava and Parallelization + A common question about RxJava is how to achieve parallelization, or emitting multiple items concurrently from an Observable. + This definition breaks the Observable contract which states that onNext() must be called sequentially and never concurrently
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Schedulers + immediate(), creates and returns a Scheduler that executes work immediately on the current thread + trampoline(), creates and returns a Scheduler that queues work on the current thread to be executed after the current work completes + newThread(), creates and returns a Scheduler that creates a new Thread for each unit of work + computation(), creates and returns a Scheduler intended for computational work + io(), creates and returns a Scheduler intended for IO-bound work (unbounded, multiple threads)
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> subscribeOn() The method subscribeOn() allows you to move the execution of the Observable code into another thread and with an specific behavior val subscription = newsManager.getNews() .subscribeOn(Schedulers.io()) .subscribe ({}, {})
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> observeOn() The observeOn() method allows to specify where to execute the functions provided in the subscribe() one val subscription = newsManager.getNews() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe ({}, {})
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Altogether Now Observable.just("Hello World") // each subscription is going to be on a new thread .subscribeOn(Schedulers.newThread()) // observation on the main thread .observeOn(AndroidSchedulers.mainThread())) .subscribe(object:Subscriber<String>(){ override fun onCompleted() { // Completed } override fun onError(e: Throwable?) { // Handle error here } override fun onNext(t: String?) { Log.e("Output",t); } })
+ ^ | | @giorgionatili +-------------------------------------+--------------+ Take Aways
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Functional Reactive Programming + FRP doesn’t solve all the problems + FRP hide complexities and make our code more readable + Getting started with FRP is simple and fast
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> RxJava & RxAndroid + RxJava and RxAndroid are not a pure FRP implementation (Sodium, Reactive- banana are pure FRP) + RxExtensions are a tool to uniform your programming paradigm
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Kotlin + Kotlin run on top of the JVM + Kotlin can help improving the readability of your code + Kotlin is extremely functional, almost everything is an expression
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Trade Off “Programmers know the benefits of everything and the tradeoffs of nothing” –Rich Hickey
+--------------X----X---X---X---X------------> +---------------------------------#MobileTea-> Resources + https://github.com/miquelbeltran/rxjava- examples + https://github.com/marukami/RxKotlin- Android-Samples + https://github.com/JakeWharton/RxBinding + https://gist.github.com/GiorgioNatili/ d4a20d4513ee544c0700854d123360d7 + https://nilhcem.github.io/swift-is-like- kotlin/
Schedule
 7:00 pm - 7:30 pm Welcome with beers and snacks 7:30 pm - 8:35 pm Screening of "Design Disruptors" 8:35 pm - 9:30 pm Networking moment and aperitif Giovedì 1 Dicembre, ore 19:00 , Luiss Enlabs, Stazione Termini, Roma DESIGN DISRUPTORS is a full-length documentary featuring design leaders and product designers from 15+ industry-toppling companies—valued at more than $1trillion dollars combined. Free, but registration is required :)
–Giorgio Natili :) “FRP programmers do it better.”

Functional Reactive Programming with Kotlin on Android - Giorgio Natili - Codemotion Milan 2016