Reactive Collections
-
Upload
aleksandar-prokopec -
Category
Software
-
view
194 -
download
0
description
Transcript of Reactive Collections
![Page 1: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/1.jpg)
1
Containers and Aggregates, Mutators and Isolates
for Reactive Programming
Aleksandar Prokopec, Philipp Haller, Martin Odersky
![Page 2: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/2.jpg)
Reactive Collections http://reactive-collections.com
2
![Page 3: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/3.jpg)
Reactive
3
![Page 4: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/4.jpg)
4
![Page 5: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/5.jpg)
5
Observables (event streams)
![Page 6: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/6.jpg)
6
Observables (event streams)
• declarative
val log = messages
.filter(_.length < 100)
.scan(_ + “\n” + _)
![Page 7: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/7.jpg)
7
Observables (event streams)
• declarative
val log = messages
.filter(_.length < 100)
.scan(_ + “\n” + _)
var log = “”
def receive = {
case s: String =>
if (s.length < 100)
log = log + “\n” + s
}
![Page 8: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/8.jpg)
8
Actors
• encapsulate mutable state
![Page 9: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/9.jpg)
9
Actors
• encapsulate mutable state
var log = “”
def receive = {
case s: String =>
if (s.length < 100)
log = log + “\n” + s
}
![Page 10: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/10.jpg)
10
Reactive collections
Isolate Reactive Channel
Actor ?
ActorRef
? Observable Observable
![Page 11: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/11.jpg)
11
Reactive values
![Page 12: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/12.jpg)
Reactive[T]
12
![Page 13: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/13.jpg)
val ticks: Reactive[Long]
13
ticks 1
1
2
2
3
3
4
4
60
60
61
61
![Page 14: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/14.jpg)
ticks onEvent { x => log.debug(s”tick no.$x”) }
14
1 2 3 4 60 61
tick no.1
tick no.2
tick no.3
tick no.4
tick no.60
tick no.61
...
![Page 15: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/15.jpg)
ticks foreach { x => log.debug(s”tick no.$x”) }
15
1 2 3 4 60 61
![Page 16: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/16.jpg)
16
for (x <- ticks) { log.debug(s”tick no.$x”) }
Single-threaded!
![Page 17: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/17.jpg)
17
Reactive combinators
![Page 18: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/18.jpg)
for (x <- ticks) yield { x / 60 }
18
![Page 19: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/19.jpg)
val seconds: Reactive[Long] = for (x <- ticks) yield { x / 60 }
19
![Page 20: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/20.jpg)
60 61
val seconds: Reactive[Long] = for (x <- ticks) yield { x / 60 }
20
ticks 1
1
2
2
3
3 60 61
seconds
0 0 0 1 1
ticks
seconds
0 0 0 1 1
![Page 21: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/21.jpg)
val days: Reactive[Long] = seconds.map(_ / 86400)
21
![Page 22: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/22.jpg)
val days: Reactive[Long] = seconds.map(_ / 86400) val secondsToday =
22
![Page 23: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/23.jpg)
val days: Reactive[Long] = seconds.map(_ / 86400) val secondsToday = (seconds zip days) { (s, d) => s – d * 86400 } 23
![Page 24: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/24.jpg)
val angle = secondsInDay.map(angleFunc)
24
![Page 25: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/25.jpg)
val angle = secondsInDay.map(angleFunc) val light = secondsInDay.map(lightFunc)
25
![Page 26: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/26.jpg)
26
![Page 27: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/27.jpg)
27
val rotate = keys
a ↓ shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys
![Page 28: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/28.jpg)
28
val rotate = keys.filter(_ == PAGEUP)
a ↓ shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys
pgup ↓ pgup ↑ filter
![Page 29: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/29.jpg)
29
val rotate = keys.filter(_ == PAGEUP) .map(_.down)
a ↓ shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys
pgup ↓ pgup ↑ filter
true false map
![Page 30: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/30.jpg)
30
if (rotate()) viewAngle += 1
true false map
![Page 31: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/31.jpg)
31
Signals
![Page 32: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/32.jpg)
32
trait Signal[T] extends Reactive[T] { def apply(): T }
![Page 33: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/33.jpg)
33
val rotate = keys.filter(_ == PAGEUP) .map(_.down) .signal(false)
true false map
signal
![Page 34: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/34.jpg)
34
val rotate: Signal[Boolean] = keys.filter(_ == PAGEUP) .map(_.down) .signal(false)
true false map
signal
![Page 35: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/35.jpg)
35
val rotate: Signal[Boolean] val ticks: Reactive[Long]
ticks
![Page 36: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/36.jpg)
36
val rotate: Signal[Boolean] val ticks: Reactive[Long]
ticks
rotate
![Page 37: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/37.jpg)
37
val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double] =
ticks
rotate
viewAngle
![Page 38: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/38.jpg)
38
val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double] = ticks.scanPast(0.0)
ticks
rotate
viewAngle
![Page 39: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/39.jpg)
39
val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double] = ticks.scanPast(0.0) { (a, _) => if (rotate()) a + 1 else a }
ticks
rotate
viewAngle
![Page 40: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/40.jpg)
40
![Page 41: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/41.jpg)
41
val velocity = ticks.scanPast(0.0) { (v, _) => } val viewAngle =
![Page 42: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/42.jpg)
42
val velocity = ticks.scanPast(0.0) { (v, _) => if (rotate()) v + 1 } val viewAngle =
![Page 43: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/43.jpg)
43
val velocity = ticks.scanPast(0.0) { (v, _) => if (rotate()) v + 1 else v – 0.5 } val viewAngle =
![Page 44: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/44.jpg)
44
val velocity = ticks.scanPast(0.0) { (v, _) => if (rotate()) v + 1 else v – 0.5 } val viewAngle = velocity.scanPast(0.0)(_ + _)
![Page 45: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/45.jpg)
45
![Page 46: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/46.jpg)
46
Reactive mutators
![Page 47: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/47.jpg)
47
class Matrix { def apply(x: Int, y: Int): Double def update(x: Int, y: Int, v: Double) }
![Page 48: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/48.jpg)
48
val screenMat: Signal[Matrix] = (projMat zip viewMat)(_ * _) val invScreenMat = screenMat.map(_.inverse)
![Page 49: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/49.jpg)
49
Reactive[immutable.Matrix[T]]
![Page 50: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/50.jpg)
50
val screenMat: Signal[Matrix] = (projMat zip viewMat)(_ * _) val invScreenMat = screenMat.map(_.inverse)
(4*4*8 + 16 + 16)*4*100 = 64 kb/s
![Page 51: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/51.jpg)
51
val screenMat = Mutable(new Matrix) (projMat, viewMat).mutate(screenMat) { (p, v) => screenMat().assignMul(p, v) } val invScreenMat = Mutable(new Matrix) screenMat.mutate(invScreenMat) { m => invScreenMat().assignInv(m) }
![Page 52: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/52.jpg)
52
Reactive collections
![Page 53: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/53.jpg)
53
![Page 54: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/54.jpg)
54
val selected: Reactive[Set[Character]]
![Page 55: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/55.jpg)
55
val selected: ReactSet[Character]
![Page 56: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/56.jpg)
56
trait ReactSet[T] extends ReactContainer[T] { def apply(x: T): Boolean }
![Page 57: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/57.jpg)
57
trait ReactContainer[T] { def inserts: Reactive[T] def removes: Reactive[T] }
![Page 58: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/58.jpg)
58
A reactive collection is a pair
of reactive values
![Page 59: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/59.jpg)
59
val selected = new ReactHashSet[Character]
![Page 60: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/60.jpg)
60
![Page 61: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/61.jpg)
61
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c)))
![Page 62: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/62.jpg)
62
class ReactContainer[T] { self => def inserts: Reactive[T] def removes: Reactive[T] def map[S](f: T => S) = new ReactContainer[S] { def inserts: Reactive[T] = self.inserts.map(f) def removes: Reactive[T] = self.removes.map(f) } }
![Page 63: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/63.jpg)
63
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
![Page 64: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/64.jpg)
64
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
![Page 65: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/65.jpg)
65
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
![Page 66: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/66.jpg)
66
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
![Page 67: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/67.jpg)
67
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
![Page 68: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/68.jpg)
68
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
![Page 69: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/69.jpg)
69
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
![Page 70: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/70.jpg)
70
val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
![Page 71: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/71.jpg)
71
Isolates
![Page 72: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/72.jpg)
72
UI isolate
class UI extends Isolate[UI.Message] { val frames = source.filter(_ == UI.Frame) val exit = source onCase { case UI.Exit => exit() } }
Source
![Page 73: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/73.jpg)
73
UI Isolate
Source
AI Isolate
Source
Channel[AI.Message]
Channel[UI.Message]
![Page 74: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/74.jpg)
74
Reactive collections
Isolate Reactive Channel
Actor ?
ActorRef
? Observable Observable
![Page 75: Reactive Collections](https://reader034.fdocuments.in/reader034/viewer/2022052508/55972d5f1a28abe0378b457a/html5/thumbnails/75.jpg)
75
Thank you!