Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Reactive Collections
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Aleksandar Prokopec
July 30, 2014
Programming
210
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Reactive Collections
Description of the reactive collections framework from the Scala 2014 workshop.
Aleksandar Prokopec
July 30, 2014
More Decks by Aleksandar Prokopec
See All by Aleksandar Prokopec
ScalaMeter in 2014
axel22
0
380
A Reactive 3D Game Engine in Scala
axel22
4
8.4k
ScalaBlitz
axel22
0
230
Work-stealing Tree Scheduler
axel22
1
110
ScalaMeter
axel22
0
170
Ctrie Data Structure
axel22
0
280
Parallel Collections Overview
axel22
0
160
Introduction to Scala
axel22
2
340
Other Decks in Programming
See All in Programming
setup-vp GitLab対応の裏側
naokihaba
0
110
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
120
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
250
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.3k
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2k
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
350
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
210
Family mrubyの進捗
kishima
1
130
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
180
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
550
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
610
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
150
Featured
See All Featured
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Un-Boring Meetings
codingconduct
0
420
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
580
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
540
Code Reviewing Like a Champion
maltzj
528
40k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
510
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
690
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!