![Page 1: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/1.jpg)
Scala.RxScaladays 2014, Berlin
Li Haoyihttps://github.com/lihaoyi/scala.rx
![Page 2: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/2.jpg)
What● libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5"
● Scala.Rx is a change-propagation library
● Reactive values which depend on each other
● Change one and they propagate the update
![Page 3: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/3.jpg)
Reactive values which depend on each other
![Page 4: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/4.jpg)
Change one and they propagate the update
![Page 5: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/5.jpg)
Motivation
var a = 1; var b = 2
val c = a + b
println(c) // 3
a = 4
println(c) // 3
![Page 6: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/6.jpg)
Motivation
var a = 1; var b = 2
def c = a + b
println(c) // 3
a = 4
println(c) // 6
![Page 7: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/7.jpg)
Motivation
var a = 1; var b = 2
def c = veryExpensiveOperation(a, b)
println(c) // 3
a = 4
println(c) // 6
![Page 8: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/8.jpg)
Motivation
var a = 1; var b = 2
def c = a + b
// onChange(c, () => ...)
a = 4
![Page 9: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/9.jpg)
Motivation
import rx._
val a = Var(1); val b = Var(2)
val c = Rx{ a() + b() }
println(c()) // 3
a() = 4
println(c()) // 6
![Page 10: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/10.jpg)
Motivation
import rx._
val a = Var(1); val b = Var(2)
val c = Rx{ a() + b() }
println(c()) // 3
a() = 4
println(c()) // 6
Obs(c){ ... do something... }
![Page 11: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/11.jpg)
What
● Var: reactive variables that are set manually
● Rx: reactive values that depend on other reactive values
● Obs: observes changes to reactive values and does things
![Page 12: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/12.jpg)
Why
● Most mutable state isn’t really “state”○ Depends on other variables○ Should be kept in sync○ Weird things happen if it falls out of sync?
● When recalculating something, you want to do it the same way you did it the first time
● Scala.Rx saves you from having to keep things in sync manually
![Page 13: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/13.jpg)
What - Observers
val a = Var(1)var count = 0val o = Obs(a){ count = a() + 1}println(count) // 2a() = 4println(count) // 5
![Page 14: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/14.jpg)
What - Propagationval a = Var(1) // 1
val b = Var(2) // 2
val c = Rx{ a() + b() } // 3val d = Rx{ c() * 5 } // 15val e = Rx{ c() + 4 } // 7val f = Rx{ d() + e() + 4 } // 26
println(f()) // 26a() = 3println(f()) // 38
![Page 15: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/15.jpg)
Exceptions
val a = Var(1L)val b = Var(2L)
val c = Rx{ a() / b() }val d = Rx{ a() * 5 }val e = Rx{ 5 / b() }val f = Rx{ a() + b() + 2 }val g = Rx{ f() + c() }
b() = 0 // uh oh
![Page 16: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/16.jpg)
Console Demo
![Page 17: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/17.jpg)
Scala.js Demo
![Page 18: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/18.jpg)
Exceptions Demo
![Page 19: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/19.jpg)
Scala.js Demo 2
![Page 20: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/20.jpg)
How
val a = Rx{b() + c()}
● Rx.apply pushes itself onto a thread-local stack before evaluating contents
● b.apply, c.apply look at who’s on top of the stack and add the dependency
![Page 21: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/21.jpg)
Propagation Strategy
● Controlled by a Propagator
● When call Var.update, how/when do its dependencies update?
![Page 22: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/22.jpg)
Propagation Strategy
● Propagator.Immediate: happens on current thread, finishes before .update returns
● Propagator.ExecContext: happens on whatever ExecutionContext is given, .update returns a Future[Unit]
● Both happen in roughly-breadth-first, topological order.
![Page 23: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/23.jpg)
Topological Order1 2 3 4
![Page 24: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/24.jpg)
Overall Characteristics
● Dependency graph constructed at runtime○ No need to live in a monad○ No need to specify what the dependencies are
● No globals, only one thread-local stack○ Easy to use as one part of a larger program.○ Small fragments of change-propagation in a larger
non-Scala.Rx world○ Easily interops with non-Scala.Rx world
![Page 25: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/25.jpg)
Limitations
● Dependency graph can change shape ○ Rxs may evaluate out of order○ Rxs may evaluate more than once
● Thread local stack doesn’t play nicely with Futures
● Rx initialization is blocking○ Can’t initialize more than one in parallel
![Page 26: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/26.jpg)
Limitations
val a = Var(1) // depth 0
val b = Rx{ a() + 1 } // depth 1
val c = Rx{ // depth 1 or 2???
if (random() > 0.5) b() + 1
else a() + 1
}
![Page 27: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/27.jpg)
Limitations
val a = Rx{ ... }
val b = Rx{ Future(a()) }
![Page 28: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/28.jpg)
Limitations
import concurrent.ExecutionContext.global
implicit val prop = {
new Propagator.ExecContext()(global)
}
val a = Var(1)
val b = Rx{ expensiveCompute(a() + 1) }
val c = Rx{ expensiveCompute(a() + 2) }
![Page 29: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/29.jpg)
Scope
● Useless in stateless web services
● Useless in pure-functional code
● Doesn’t support a rich event-stream API
● Doesn’t support channels, coroutines, async
![Page 30: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/30.jpg)
Works on Android too!
// create a reactive variableval caption = rx.Var("Olá")// set text to “Olá”textView <~ caption.map(text)// text automatically updates to “Adeus”caption.update("Adeus")
● Example taken from http://macroid.github.io/guide/Advanced.html
● Warning: I haven't tried it myself
![Page 31: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/31.jpg)
What
● Var: reactive variables that are set manually
● Rx: reactive values that depend on other reactive values
● Obs: observes changes to reactive values and does things
![Page 32: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/32.jpg)
Past Work
● Lots of existing FRP libraries
● Most are written in Haskell○ Or some custom dialect of Haskell○ Or some custom dialect of Java
● None of them interop easily with “normal” code
![Page 33: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/33.jpg)
Future Work
● Clean up implementation○ Internals are a big mess○ Lots of code related to multithreading useless on
ScalaJS and should be separated out
● Experiment with a persistent file backend?○ Currently very similar to SBT’s dataflow graph○ ...but much easier to use○ Maybe it’s generic enough to be useful?
![Page 34: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/34.jpg)
If you liked the Demo● Scala.js - 0.5.0, by sjrd and gzm0
● Scalatags - 0.3.0
● Scala.Rx - 0.2.5
● Workbench - 0.1.2
● Workbench-Example-App
![Page 35: Scala - lihaoyi.com · What libraryDependencies += "com.scalarx" %% "scalarx" % "0.2.5" Scala.Rx is a change-propagation library Reactive values which depend on each other](https://reader030.vdocuments.us/reader030/viewer/2022040711/5e140e4064a5815e5f1d8961/html5/thumbnails/35.jpg)
Questions?
Ask me about● Scala.React● Multithreaded Execution Model● Memory Modal● Delimited Continuations● Running on ScalaJS