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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
高速開発のためのコード整理術
sutetotanuki
1
390
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
500
AIエージェント、”どう作るか”で差は出るか? / AI Agents: Does the "How" Make a Difference?
rkaga
4
2k
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
650
Fragmented Architectures
denyspoltorak
0
150
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
160
Kotlin Multiplatform Meetup - Compose Multiplatform 외부 의존성 아키텍처 설계부터 운영까지
wisemuji
0
190
15年続くIoTサービスのSREエンジニアが挑む分散トレーシング導入
melonps
2
170
開発者から情シスまで - 多様なユーザー層に届けるAPI提供戦略 / Postman API Night Okinawa 2026 Winter
tasshi
0
200
インターン生でもAuth0で認証基盤刷新が出来るのか
taku271
0
190
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
170
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
515
110k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
60
42k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
6.9k
The Curious Case for Waylosing
cassininazir
0
230
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
63
How to train your dragon (web standard)
notwaldorf
97
6.5k
Documentation Writing (for coders)
carmenintech
77
5.2k
Six Lessons from altMBA
skipperchong
29
4.1k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
240
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
1.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
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!