-
Notifications
You must be signed in to change notification settings - Fork 41
/
13-why-reactivity.Rmd
276 lines (200 loc) · 7.34 KB
/
13-why-reactivity.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# Why reactivity?
**Learning objectives**
We want to improve our **intuitive understanding** based on applying reactivity.
- What is reactivity or reactive programming?
- Why is it used in Shiny?
## Shiny is good magic {-}
If you check the layers of reactive programming:
- You won't find a pile of heuristics, **special cases**, and **hacks**
- The magic comes from **simple concepts combined** in consistent ways
## What is reactive programming? {-}
- It's a paradigm which focuses on **values that change** over time, and calculations and actions that **depend on those values**
- It is concerned with **data streams** (_sequence of data elements_) and the **propagation of changes**
![](images/13-why-reactivity/01-dominos.webp)
## Why reactive programming in Shiny? {-}
- **The problem**
- We want to keep sync inputs & outputs
- But we need to minimize the computation
- **The solution**
- Outputs and reactive expressions change _if and only if_ their inputs change
## Why can't you use variables? {-}
**Variables don't update automatically** when a prior value changes
```{r why-not-variables, eval = FALSE}
temp_c <- 10
temp_f <- (temp_c * 9 / 5) + 32
temp_f
#> [1] 50
temp_c <- 30
# temp_f not automatically updated
temp_f
#> [1] 50
```
## Why can't you use functions? {-}
They address the issue of automatic updating but require **excessive computation**.
```{r what-about-functions, eval = FALSE}
temp_c <- 10
temp_f <- function() {
message("Converting")
(temp_c * 9 / 5) + 32
}
temp_f()
#> Converting
#> [1] 50
# temp_f automatically updated
temp_c <- -3
temp_f()
#> Converting
#> [1] 26.6
# but does unnecessary computation (recomputes every time it's called)
temp_f()
#> Converting
#> [1] 26.6
```
## Event-driven programming {-}
This method callback functions that run in **response to events** like:
- Clicking a button
- Running a function to process order
We can define events using the `R6` package in R.
```{r event-driven-programming-class-def, eval = FALSE}
DynamicValue <- R6::R6Class("DynamicValue", list(
value = NULL,
on_update = NULL,
get = function() self$value,
set = function(value) {
self$value <- value
if (!is.null(self$on_update))
self$on_update(value)
invisible(self)
},
onUpdate = function(on_update) {
self$on_update <- on_update
invisible(self)
}
))
```
## Event-driven limitation {-}
It solves problem of _unnecessary computation_, but makes **hard to track which inputs** affect which computations.
```{r event-driven-programming-class-usage, eval = FALSE}
temp_c <- DynamicValue$new()
temp_c$onUpdate(function(value) {
message("Converting")
temp_f <<- (value * 9 / 5) + 32
})
temp_c$set(10)
#> Converting
temp_f
#> [1] 50
temp_c$set(-3)
#> Converting
temp_f
#> [1] 26.6
```
## Reactive programming {-}
Reactive programming combines features of solutions we've seen so far.
```{r reactive-programming, eval = FALSE}
library(shiny)
reactiveConsole(TRUE) # let's us use reactivity in console
temp_c <- reactiveVal(10) # create
temp_c() # get
#> [1] 10
temp_c(20) # set
temp_c() # get
#> [1] 20
temp_f <- reactive({
message("Converting")
(temp_c() * 9 / 5) + 32
})
temp_f()
#> Converting
#> [1] 68
# temp_f automatically updates
temp_c(-10)
temp_f()
#> Converting
#> [1] 14
# _and_ only computes when needed (don't see "Converting")
temp_f()
#> [1] 14
```
## Properties of reactive expressions {-}
- **Lazy**: only does work when it's called
- **Cached**: Saves last result, to only work on first call
## History of reactive programming {-}
- It started with spreadsheets! (VisCalc, 1979)
- Not really studied academically until late 1990s
- In 2010s became mainstream
- JavaScript UI frameworks: Knockout, Ember, Meteor _(inspiration for Shiny)_
- Now: React, Vue, Angular
- "Reactive programming" is a **general term** a lot of different implementations can fill that concept
## Meeting Videos
### Cohort 1
`r knitr::include_url("https://www.youtube.com/embed/tXShS1PVKlY")`
<details>
<summary> Meeting chat log </summary>
```
00:01:19 Russ Hyde: Hi Everyone4
00:05:22 Russ Hyde: There are lots of chapters available if anyone would like to do a talk over the next few weeks.
00:05:37 Russ Hyde: Myself and Diamantis have the next couple of weeks planned.
00:06:16 Russ Hyde: But there's another chapter in the Reactivity section and all-but-one of the best-practices chapters available
00:06:50 Andrew MacDonald (he/him): hello everyone! :
00:06:53 Andrew MacDonald (he/him): :D
00:06:57 Russ Hyde: Those chapters take us up to mid-august.
00:07:13 Russ Hyde: And hopefully we'll all be expert shiny devs by then ...
00:09:14 Layla Bouzoubaa: I think I can do functions
00:09:19 Layla Bouzoubaa: *think*
00:10:44 Andrew MacDonald (he/him): I could be an understudy for ch16 :)
00:12:03 Russ Hyde: Layla, if you'd like to do functions that would be great
00:12:33 Layla Bouzoubaa: Ok, I’ll go ahead and put it in the books
00:12:39 Layla Bouzoubaa: 6/29
00:12:55 Russ Hyde: :)
00:31:55 priyanka gagneja: Yeah {react log}
00:41:21 priyanka gagneja: @Layla - you might like this https://www.youtube.com/watch?v=8VjkatOf7Bs
00:48:49 Layla Bouzoubaa: Sorry everyone, I need to hop off. See you next week!!
00:49:31 priyanka gagneja: By Maya Gans :P
00:50:09 priyanka gagneja: Well .. I meant author of the book ‘javascript for R’ that AB brought up
00:52:08 Andrew MacDonald (he/him): this was a lighter chapter! touches on a lot of topics though
00:52:20 Andrew MacDonald (he/him): yeah thanks Andrew B., great summary
```
</details>
### Cohort 2
`r knitr::include_url("https://www.youtube.com/embed/8AK_qPbK4MA")`
<details>
<summary> Meeting chat log </summary>
```
00:43:00 Ryan Metcalf: Not sure if this quite answers the question of cache’ing variables in a Shiny Server -> UI handshake. The comment I made was toward “threading”. The article does clarify the differences. https://www.digitalocean.com/community/tutorials/apache-vs-nginx-practical-considerations
```
</details>
### Cohort 3
`r knitr::include_url("https://www.youtube.com/embed/VMX95Dap39Y")`
<details>
<summary>Meeting chat log</summary>
```
00:29:06 Ryan Metcalf: “The R6 package provides an implementation of encapsulated object-oriented programming for R (also sometimes referred to as classical object-oriented programming)”. https://r6.r-lib.org/articles/Introduction.html
```
</details>
### Cohort 4
`r knitr::include_url("https://www.youtube.com/embed/egmNwbddpm4")`
<details>
<summary>Meeting chat log</summary>
```
00:26:28 Lucio Cornejo: why do your coworkers not consider Shiny a web app?
00:26:53 Trevin: I don’t have any links 😄
00:27:05 Matthew Efoli: Reacted to "I don’t have any lin..." with 😄
00:27:15 Trevin: I’ll second that talk, I was lucky enough to see it in person
00:27:41 Lucio Cornejo: please someone find that link :)
00:28:00 Trevin: https://www.youtube.com/watch?v=HpqLXB_TnpI
00:28:13 Trevin: The Past and Future of Shiny (2022) Joe Cheng
00:28:16 Lydia Gibson: You beat me to it loll
00:28:29 Lydia Gibson: I got to see it in person as well. It was amazing!
00:28:40 Lucio Cornejo: oooh that's weird, I had not seen it. Thank you
00:30:58 Lucio Cornejo: it's me hehe sorry
```
</details>
### Cohort 5
`r knitr::include_url("https://www.youtube.com/embed/URL")`
<details>
<summary>Meeting chat log</summary>
```
LOG
```
</details>