Reactive Collections

Aleksandar Prokopec
Aleksandar ProkopecSoftware Engineer, Doctoral Assistant at EPFL
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 
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!
1 of 75

Recommended

Monadologie by
MonadologieMonadologie
Monadologieleague
3.6K views58 slides
Scala by Luc Duponcheel by
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc DuponcheelStephan Janssen
635 views91 slides
Struct examples by
Struct examplesStruct examples
Struct examplesmondalakash2012
350 views33 slides
A bit about Scala by
A bit about ScalaA bit about Scala
A bit about ScalaVladimir Parfinenko
1.1K views32 slides
Scala for Jedi by
Scala for JediScala for Jedi
Scala for JediVladimir Parfinenko
1.2K views33 slides
D3.js workshop by
D3.js workshopD3.js workshop
D3.js workshopAnton Katunin
87.1K views105 slides

More Related Content

What's hot

The Ring programming language version 1.7 book - Part 40 of 196 by
The Ring programming language version 1.7 book - Part 40 of 196The Ring programming language version 1.7 book - Part 40 of 196
The Ring programming language version 1.7 book - Part 40 of 196Mahmoud Samir Fayed
15 views10 slides
Type classes 101 - classification beyond inheritance by
Type classes 101 - classification beyond inheritanceType classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceAlexey Raga
480 views42 slides
Test s velocity_15_5_4 by
Test s velocity_15_5_4Test s velocity_15_5_4
Test s velocity_15_5_4Kunihiko Saito
278 views30 slides
The Ring programming language version 1.7 book - Part 71 of 196 by
The Ring programming language version 1.7 book - Part 71 of 196The Ring programming language version 1.7 book - Part 71 of 196
The Ring programming language version 1.7 book - Part 71 of 196Mahmoud Samir Fayed
7 views10 slides
Error Handling in Scala by
Error Handling in ScalaError Handling in Scala
Error Handling in ScalaDaniel Pfeiffer
559 views38 slides
Futures e abstração - QCon São Paulo 2015 by
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Leonardo Borges
1.6K views60 slides

What's hot(20)

The Ring programming language version 1.7 book - Part 40 of 196 by Mahmoud Samir Fayed
The Ring programming language version 1.7 book - Part 40 of 196The Ring programming language version 1.7 book - Part 40 of 196
The Ring programming language version 1.7 book - Part 40 of 196
Type classes 101 - classification beyond inheritance by Alexey Raga
Type classes 101 - classification beyond inheritanceType classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritance
Alexey Raga480 views
The Ring programming language version 1.7 book - Part 71 of 196 by Mahmoud Samir Fayed
The Ring programming language version 1.7 book - Part 71 of 196The Ring programming language version 1.7 book - Part 71 of 196
The Ring programming language version 1.7 book - Part 71 of 196
Futures e abstração - QCon São Paulo 2015 by Leonardo Borges
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015
Leonardo Borges1.6K views
Numerical Method Assignment by ashikul akash
Numerical Method AssignmentNumerical Method Assignment
Numerical Method Assignment
ashikul akash79 views
The Ring programming language version 1.2 book - Part 24 of 84 by Mahmoud Samir Fayed
The Ring programming language version 1.2 book - Part 24 of 84The Ring programming language version 1.2 book - Part 24 of 84
The Ring programming language version 1.2 book - Part 24 of 84
Cg my own programs by Amit Kapoor
Cg my own programsCg my own programs
Cg my own programs
Amit Kapoor3.9K views
Extend R with Rcpp!!! by mickey24
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!
mickey241.4K views
Intro to Game Programming by Richard Jones
Intro to Game ProgrammingIntro to Game Programming
Intro to Game Programming
Richard Jones2.6K views
SOLID principles in practice: the Clean Architecture by Fabio Collini
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
Fabio Collini1.6K views
Hitchhiker's Guide to Functional Programming by Sergey Shishkin
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional Programming
Sergey Shishkin207 views

Similar to Reactive Collections

ScalaDays 2014 - Reactive Scala 3D Game Engine by
ScalaDays 2014 - Reactive Scala 3D Game Engine ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine Aleksandar Prokopec
5.2K views97 slides
The Ring programming language version 1.3 book - Part 16 of 88 by
The Ring programming language version 1.3 book - Part 16 of 88The Ring programming language version 1.3 book - Part 16 of 88
The Ring programming language version 1.3 book - Part 16 of 88Mahmoud Samir Fayed
19 views10 slides
ScalaMeter 2014 by
ScalaMeter 2014ScalaMeter 2014
ScalaMeter 2014Aleksandar Prokopec
2.3K views77 slides
2.3 implicits by
2.3 implicits2.3 implicits
2.3 implicitsfuturespective
439 views13 slides
Crushing the Head of the Snake by Robert Brewer PyData SV 2014 by
Crushing the Head of the Snake by Robert Brewer PyData SV 2014Crushing the Head of the Snake by Robert Brewer PyData SV 2014
Crushing the Head of the Snake by Robert Brewer PyData SV 2014PyData
1.4K views68 slides
Funtional Reactive Programming with Examples in Scala + GWT by
Funtional Reactive Programming with Examples in Scala + GWTFuntional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWTVasil Remeniuk
7.6K views34 slides

Similar to Reactive Collections(20)

ScalaDays 2014 - Reactive Scala 3D Game Engine by Aleksandar Prokopec
ScalaDays 2014 - Reactive Scala 3D Game Engine ScalaDays 2014 - Reactive Scala 3D Game Engine
ScalaDays 2014 - Reactive Scala 3D Game Engine
Aleksandar Prokopec5.2K views
The Ring programming language version 1.3 book - Part 16 of 88 by Mahmoud Samir Fayed
The Ring programming language version 1.3 book - Part 16 of 88The Ring programming language version 1.3 book - Part 16 of 88
The Ring programming language version 1.3 book - Part 16 of 88
Crushing the Head of the Snake by Robert Brewer PyData SV 2014 by PyData
Crushing the Head of the Snake by Robert Brewer PyData SV 2014Crushing the Head of the Snake by Robert Brewer PyData SV 2014
Crushing the Head of the Snake by Robert Brewer PyData SV 2014
PyData1.4K views
Funtional Reactive Programming with Examples in Scala + GWT by Vasil Remeniuk
Funtional Reactive Programming with Examples in Scala + GWTFuntional Reactive Programming with Examples in Scala + GWT
Funtional Reactive Programming with Examples in Scala + GWT
Vasil Remeniuk7.6K views
Constraint Programming in Haskell by David Overton
Constraint Programming in HaskellConstraint Programming in Haskell
Constraint Programming in Haskell
David Overton4.3K views
The Ring programming language version 1.2 book - Part 14 of 84 by Mahmoud Samir Fayed
The Ring programming language version 1.2 book - Part 14 of 84The Ring programming language version 1.2 book - Part 14 of 84
The Ring programming language version 1.2 book - Part 14 of 84
Apache Spark for Library Developers with William Benton and Erik Erlandson by Databricks
 Apache Spark for Library Developers with William Benton and Erik Erlandson Apache Spark for Library Developers with William Benton and Erik Erlandson
Apache Spark for Library Developers with William Benton and Erik Erlandson
Databricks596 views
Computer Graphics in Java and Scala - Part 1b by Philip Schwarz
Computer Graphics in Java and Scala - Part 1bComputer Graphics in Java and Scala - Part 1b
Computer Graphics in Java and Scala - Part 1b
Philip Schwarz261 views
Matematika Dasar (exponen,dan banyak lagi) by Lufikome
Matematika Dasar (exponen,dan banyak lagi)Matematika Dasar (exponen,dan banyak lagi)
Matematika Dasar (exponen,dan banyak lagi)
Lufikome1 view
Introduction to Neural Networks and Deep Learning from Scratch by Ahmed BESBES
Introduction to Neural Networks and Deep Learning from ScratchIntroduction to Neural Networks and Deep Learning from Scratch
Introduction to Neural Networks and Deep Learning from Scratch
Ahmed BESBES14.6K views
Sistemas de control para ingenieria 3ra edicion norman s. nise sol by Nielsy Quiroga
Sistemas de control para ingenieria  3ra edicion  norman s. nise solSistemas de control para ingenieria  3ra edicion  norman s. nise sol
Sistemas de control para ingenieria 3ra edicion norman s. nise sol
Nielsy Quiroga11.4K views
Time Series Analysis and Mining with R by Yanchang Zhao
Time Series Analysis and Mining with RTime Series Analysis and Mining with R
Time Series Analysis and Mining with R
Yanchang Zhao17K views

Recently uploaded

FOSSLight Community Day 2023-11-30 by
FOSSLight Community Day 2023-11-30FOSSLight Community Day 2023-11-30
FOSSLight Community Day 2023-11-30Shane Coughlan
6 views18 slides
The Path to DevOps by
The Path to DevOpsThe Path to DevOps
The Path to DevOpsJohn Valentino
5 views6 slides
360 graden fabriek by
360 graden fabriek360 graden fabriek
360 graden fabriekinfo33492
143 views25 slides
predicting-m3-devopsconMunich-2023.pptx by
predicting-m3-devopsconMunich-2023.pptxpredicting-m3-devopsconMunich-2023.pptx
predicting-m3-devopsconMunich-2023.pptxTier1 app
7 views24 slides
Using Qt under LGPL-3.0 by
Using Qt under LGPL-3.0Using Qt under LGPL-3.0
Using Qt under LGPL-3.0Burkhard Stubert
13 views11 slides
Generic or specific? Making sensible software design decisions by
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
6 views60 slides

Recently uploaded(20)

FOSSLight Community Day 2023-11-30 by Shane Coughlan
FOSSLight Community Day 2023-11-30FOSSLight Community Day 2023-11-30
FOSSLight Community Day 2023-11-30
Shane Coughlan6 views
360 graden fabriek by info33492
360 graden fabriek360 graden fabriek
360 graden fabriek
info33492143 views
predicting-m3-devopsconMunich-2023.pptx by Tier1 app
predicting-m3-devopsconMunich-2023.pptxpredicting-m3-devopsconMunich-2023.pptx
predicting-m3-devopsconMunich-2023.pptx
Tier1 app7 views
Generic or specific? Making sensible software design decisions by Bert Jan Schrijver
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
Introduction to Git Source Control by John Valentino
Introduction to Git Source ControlIntroduction to Git Source Control
Introduction to Git Source Control
John Valentino6 views
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated... by TomHalpin9
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
TomHalpin96 views
Sprint 226 by ManageIQ
Sprint 226Sprint 226
Sprint 226
ManageIQ10 views
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by Lisi Hocke
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Lisi Hocke35 views
predicting-m3-devopsconMunich-2023-v2.pptx by Tier1 app
predicting-m3-devopsconMunich-2023-v2.pptxpredicting-m3-devopsconMunich-2023-v2.pptx
predicting-m3-devopsconMunich-2023-v2.pptx
Tier1 app9 views
FIMA 2023 Neo4j & FS - Entity Resolution.pptx by Neo4j
FIMA 2023 Neo4j & FS - Entity Resolution.pptxFIMA 2023 Neo4j & FS - Entity Resolution.pptx
FIMA 2023 Neo4j & FS - Entity Resolution.pptx
Neo4j17 views
tecnologia18.docx by nosi6702
tecnologia18.docxtecnologia18.docx
tecnologia18.docx
nosi67025 views
Top-5-production-devconMunich-2023-v2.pptx by Tier1 app
Top-5-production-devconMunich-2023-v2.pptxTop-5-production-devconMunich-2023-v2.pptx
Top-5-production-devconMunich-2023-v2.pptx
Tier1 app6 views
Ports-and-Adapters Architecture for Embedded HMI by Burkhard Stubert
Ports-and-Adapters Architecture for Embedded HMIPorts-and-Adapters Architecture for Embedded HMI
Ports-and-Adapters Architecture for Embedded HMI
Burkhard Stubert26 views
Quality Engineer: A Day in the Life by John Valentino
Quality Engineer: A Day in the LifeQuality Engineer: A Day in the Life
Quality Engineer: A Day in the Life
John Valentino7 views

Reactive Collections

  • 1. 1 Containers and Aggregates, Mutators and Isolates for Reactive Programming Aleksandar Prokopec, Philipp Haller, Martin Odersky
  • 4. 4
  • 6. 6 Observables (event streams) • declarative val log = messages .filter(_.length < 100) .scan(_ + “n” + _)
  • 7. 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. 8 Actors • encapsulate mutable state
  • 9. 9 Actors • encapsulate mutable state var log = “” def receive = { case s: String => if (s.length < 100) log = log + “n” + s }
  • 10. 10 Reactive collections Isolate Reactive Channel Actor ? ActorRef ? Observable Observable
  • 13. val ticks: Reactive[Long] 13 ticks 1 1 2 2 3 3 4 4 60 60 61 61
  • 14. 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 ...
  • 15. ticks foreach { x => log.debug(s”tick no.$x”) } 15 1 2 3 4 60 61
  • 16. 16 for (x <- ticks) { log.debug(s”tick no.$x”) } Single-threaded!
  • 18. for (x <- ticks) yield { x / 60 } 18
  • 19. val seconds: Reactive[Long] = for (x <- ticks) yield { x / 60 } 19
  • 20. 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 1
  • 21. val days: Reactive[Long] = seconds.map(_ / 86400) 21
  • 22. val days: Reactive[Long] = seconds.map(_ / 86400) val secondsToday = 22
  • 23. val days: Reactive[Long] = seconds.map(_ / 86400) val secondsToday = (seconds zip days) { (s, d) => s – d * 86400 } 23
  • 24. val angle = secondsInDay.map(angleFunc) 24
  • 25. val angle = secondsInDay.map(angleFunc) val light = secondsInDay.map(lightFunc) 25
  • 26. 26
  • 27. 27 val rotate = keys a ↓ shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys
  • 28. 28 val rotate = keys.filter(_ == PAGEUP) a ↓ shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys pgup ↓ pgup ↑ filter
  • 29. 29 val rotate = keys.filter(_ == PAGEUP) .map(_.down) a ↓ shift ↓ a ↑ shift ↑ pgup ↓ pgup ↑ keys pgup ↓ pgup ↑ filter true false map
  • 30. 30 if (rotate()) viewAngle += 1 true false map
  • 32. 32 trait Signal[T] extends Reactive[T] { def apply(): T }
  • 33. 33 val rotate = keys.filter(_ == PAGEUP) .map(_.down) .signal(false) true false map signal
  • 34. 34 val rotate: Signal[Boolean] = keys.filter(_ == PAGEUP) .map(_.down) .signal(false) true false map signal
  • 35. 35 val rotate: Signal[Boolean] val ticks: Reactive[Long] ticks
  • 36. 36 val rotate: Signal[Boolean] val ticks: Reactive[Long] ticks rotate
  • 37. 37 val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double] = ticks rotate viewAngle
  • 38. 38 val rotate: Signal[Boolean] val ticks: Reactive[Long] val viewAngle: Signal[Double] = ticks.scanPast(0.0) ticks rotate viewAngle
  • 39. 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. 40
  • 41. 41 val velocity = ticks.scanPast(0.0) { (v, _) => } val viewAngle =
  • 42. 42 val velocity = ticks.scanPast(0.0) { (v, _) => if (rotate()) v + 1 } val viewAngle =
  • 43. 43 val velocity = ticks.scanPast(0.0) { (v, _) => if (rotate()) v + 1 else v – 0.5 } val viewAngle =
  • 44. 44 val velocity = ticks.scanPast(0.0) { (v, _) => if (rotate()) v + 1 else v – 0.5 } val viewAngle = velocity.scanPast(0.0)(_ + _)
  • 45. 45
  • 47. 47 class Matrix { def apply(x: Int, y: Int): Double def update(x: Int, y: Int, v: Double) }
  • 48. 48 val screenMat: Signal[Matrix] = (projMat zip viewMat)(_ * _) val invScreenMat = screenMat.map(_.inverse)
  • 50. 50 val screenMat: Signal[Matrix] = (projMat zip viewMat)(_ * _) val invScreenMat = screenMat.map(_.inverse) (4*4*8 + 16 + 16)*4*100 = 64 kb/s
  • 51. 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) }
  • 53. 53
  • 54. 54 val selected: Reactive[Set[Character]]
  • 55. 55 val selected: ReactSet[Character]
  • 56. 56 trait ReactSet[T] extends ReactContainer[T] { def apply(x: T): Boolean }
  • 57. 57 trait ReactContainer[T] { def inserts: Reactive[T] def removes: Reactive[T] }
  • 58. 58 A reactive collection is a pair of reactive values
  • 59. 59 val selected = new ReactHashSet[Character]
  • 60. 60
  • 61. 61 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c)))
  • 62. 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. 63 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
  • 64. 64 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
  • 65. 65 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
  • 66. 66 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .to[ReactHashMap]
  • 67. 67 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
  • 68. 68 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
  • 69. 69 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
  • 70. 70 val selected = new ReactHashSet[Character] val decorations = selected .map(c => (c, decoFor(c))) .react.to[ReactHashMap]
  • 72. 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. 73 UI Isolate Source AI Isolate Source Channel[AI.Message]   Channel[UI.Message]
  • 74. 74 Reactive collections Isolate Reactive Channel Actor ? ActorRef ? Observable Observable