Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Reactive Collections
Search
Aleksandar Prokopec
July 30, 2014
Programming
0
200
Reactive Collections
Description of the reactive collections framework from the Scala 2014 workshop.
Aleksandar Prokopec
July 30, 2014
Tweet
Share
More Decks by Aleksandar Prokopec
See All by Aleksandar Prokopec
ScalaMeter in 2014
axel22
0
350
A Reactive 3D Game Engine in Scala
axel22
4
8.3k
ScalaBlitz
axel22
0
220
Work-stealing Tree Scheduler
axel22
1
85
ScalaMeter
axel22
0
150
Ctrie Data Structure
axel22
0
240
Parallel Collections Overview
axel22
0
110
Introduction to Scala
axel22
2
310
Other Decks in Programming
See All in Programming
CSC307 Lecture 09
javiergs
PRO
1
830
AIによる高速開発をどう制御するか? ガードレール設置で開発速度と品質を両立させたチームの事例
tonkotsuboy_com
7
2k
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
CSC307 Lecture 07
javiergs
PRO
0
550
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
190
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
690
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
4.3k
高速開発のためのコード整理術
sutetotanuki
1
390
Implementation Patterns
denyspoltorak
0
280
AtCoder Conference 2025
shindannin
0
1k
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
680
今から始めるClaude Code超入門
448jp
7
8.5k
Featured
See All Featured
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
57
50k
How to Ace a Technical Interview
jacobian
281
24k
Balancing Empowerment & Direction
lara
5
880
Making the Leap to Tech Lead
cromwellryan
135
9.7k
Everyday Curiosity
cassininazir
0
130
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.9k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.7k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
3.9k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
61
52k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
430
Transcript
1 Containers and Aggregates, Mutators and Isolates for Reactive Programming
Aleksandar Prokopec, Philipp Haller, Martin Odersky
Reactive Collections http://reactive-collections.com 2
Reactive 3
4
5 Observables (event streams)
6 Observables (event streams) • declarative val log = messages
.filter(_.length < 100) .scan(_ + “\n” + _)
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 }
8 Actors • encapsulate mutable state
9 Actors • encapsulate mutable state var log = “”
def receive = { case s: String => if (s.length < 100) log = log + “\n” + s }
10 Reactive collections Isolate Reactive Channel Actor ? ActorRef ?
Observable Observable
11 Reactive values
Reactive[T] 12
val ticks: Reactive[Long] 13 ticks 1 1 2 2 3
3 4 4 60 60 61 61
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 ...
ticks foreach { x => log.debug(s”tick no.$x”) } 15 1
2 3 4 60 61
16 for (x <- ticks) { log.debug(s”tick no.$x”) } Single-threaded!
17 Reactive combinators
for (x <- ticks) yield { x / 60 }
18
val seconds: Reactive[Long] = for (x <- ticks) yield {
x / 60 } 19
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
val days: Reactive[Long] = seconds.map(_ / 86400) 21
val days: Reactive[Long] = seconds.map(_ / 86400) val secondsToday =
22
val days: Reactive[Long] = seconds.map(_ / 86400) val secondsToday =
(seconds zip days) { (s, d) => s – d * 86400 } 23
val angle = secondsInDay.map(angleFunc) 24
val angle = secondsInDay.map(angleFunc) val light = secondsInDay.map(lightFunc) 25
26
27 val rotate = keys a ↓ shift ↓ a
↑ shift ↑ pgup ↓ pgup ↑ keys
28 val rotate = keys.filter(_ == PAGEUP) a ↓ shift
↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys pgup ↓ pgup ↑ filter
29 val rotate = keys.filter(_ == PAGEUP) .map(_.down) a ↓
shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys pgup ↓ pgup ↑ filter true false map
30 if (rotate()) viewAngle += 1 true false map
31 Signals
32 trait Signal[T] extends Reactive[T] { def apply(): T }
33 val rotate = keys.filter(_ == PAGEUP) .map(_.down) .signal(false) true
false map signal
34 val rotate: Signal[Boolean] = keys.filter(_ == PAGEUP) .map(_.down) .signal(false)
true false map signal
35 val rotate: Signal[Boolean] val ticks: Reactive[Long] ticks
36 val rotate: Signal[Boolean] val ticks: Reactive[Long] ticks rotate
37 val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double]
= ticks rotate viewAngle
38 val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double]
= ticks.scanPast(0.0) ticks rotate viewAngle
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
40
41 val velocity = ticks.scanPast(0.0) { (v, _) => }
val viewAngle =
42 val velocity = ticks.scanPast(0.0) { (v, _) => if
(rotate()) v + 1 } val viewAngle =
43 val velocity = ticks.scanPast(0.0) { (v, _) => if
(rotate()) v + 1 else v – 0.5 } val viewAngle =
44 val velocity = ticks.scanPast(0.0) { (v, _) => if
(rotate()) v + 1 else v – 0.5 } val viewAngle = velocity.scanPast(0.0)(_ + _)
45
46 Reactive mutators
47 class Matrix { def apply(x: Int, y: Int): Double
def update(x: Int, y: Int, v: Double) }
48 val screenMat: Signal[Matrix] = (projMat zip viewMat)(_ * _)
val invScreenMat = screenMat.map(_.inverse)
49 Reactive[immutable.Matrix[T]]
50 val screenMat: Signal[Matrix] = (projMat zip viewMat)(_ * _)
val invScreenMat = screenMat.map(_.inverse) (4*4*8 + 16 + 16)*4*100 = 64 kb/s
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) }
52 Reactive collections
53
54 val selected: Reactive[Set[Character]]
55 val selected: ReactSet[Character]
56 trait ReactSet[T] extends ReactContainer[T] { def apply(x: T): Boolean
}
57 trait ReactContainer[T] { def inserts: Reactive[T] def removes: Reactive[T]
}
58 A reactive collection is a pair of reactive values
59 val selected = new ReactHashSet[Character]
60
61 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c)))
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) } }
63 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .to[ReactHashMap]
64 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .to[ReactHashMap]
65 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .to[ReactHashMap]
66 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .to[ReactHashMap]
67 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .react.to[ReactHashMap]
68 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .react.to[ReactHashMap]
69 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .react.to[ReactHashMap]
70 val selected = new ReactHashSet[Character] val decorations = selected
.map(c => (c, decoFor(c))) .react.to[ReactHashMap]
71 Isolates
72 UI isolate class UI extends Isolate[UI.Message] { val frames
= source.filter(_ == UI.Frame) val exit = source onCase { case UI.Exit => exit() } } Source
73 UI Isolate Source AI Isolate Source Channel[AI.Message]
Channel[UI.Message]
74 Reactive collections Isolate Reactive Channel Actor ? ActorRef ?
Observable Observable
75 Thank you!