Reactivity Intro

Reactivity overview

Agenda

  • Reactivity overview

  • How do other frameworks work?

  • Reactive programming

  • Walking the graph

  • Your turn

  • Conclusion

How did Shiny do that?

How did Shiny do that?

  • We told Shiny what to do
  • We didn’t tell Shiny when to do it

How do other frameworks work?

Agenda

  • Reactivity overview

  • How do other frameworks work?

  • Reactive programming

  • Walking the graph

  • Your turn

  • Conclusion

How do other frameworks work?

Other web application frameworks use event-driven programming:

  • Streamlit

    • Re-render everything everywhere all the time
  • Dash / Panel / Gradio

    • Define callback functions

Using callback functions is hard!

  • Every callback introduces side effects
  • Callbacks are hard to reason about, hard to compose
  • Bugs are subtle, conditional on sequences of events
  • In short: “callback hell”
# This is not how shiny works!
library(gWidgets)
txt <- gtext("Customize me", container = gwindow(),
  handler = function(h, ...) {
    # Do something in response to text changing
  }
)
btn <- gbutton("Click me", container = gwindow(),
  handler = function(h, ...) {
    # Do something in response to a button click
  }
)

Event driven programming: summary

  • You have to do it
  • Easy to get wrong
  • Hard to tell when you get it wrong

Reactive programming

Agenda

  • Reactivity overview

  • How do other frameworks work?

  • Reactive programming

  • Walking the graph

  • Your turn

  • Conclusion

Is there a better way?

Note

  • Infer the relationships between components
  • Build a computation graph

The better way: reactivity

  • Shiny does not infer relationships by analyzing the source code
    • Many ways that would break down!
  • Not static analysis, but rather, runtime tracing
    • The underlying mechanism is simple, reliable, and intuitive
    • The shiny team have more than 10 years of real-world experience with this form of reactivity

Drawing a reactive graph

Shiny express app:

from shiny.express import input, render, ui

ui.input_slider("n", "N", 0, 100, 20)
@render.text
def txt():
    return f"2 * n is {input.n() * 2}"

Reactive graph:

Slider
Recipe
Text

Walking the graph

Agenda

  • Reactivity overview

  • How do other frameworks work?

  • Reactive programming

  • Walking the graph

  • Your turn

  • Conclusion

Initial state

Slider
Text

Calculate the text

Slider
Text

Final state

Slider
Text

Slider changes

Slider
Text

Invalidates

Slider
Text

Forget dependencies

Slider
Text

Recalculate

Slider
Text

Recompute the graph

Slider
Text

Updated state

Slider
Text

Your turn

Agenda

  • Reactivity overview

  • How do other frameworks work?

  • Reactive programming

  • Walking the graph

  • Your turn

  • Conclusion

Your turn

Draw the graph of this application:

Hint: you need 4 elements and draw the arrows between these.

Solution: Initial state

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Calculate scatter plot

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Calculate scatter plot

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Calculate distribution

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Calculate distribution

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Reactive graph

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Slider changes

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Invalidated

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Forget dependencies

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Recalculate

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Recalculate

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Recalculate

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Recalculate

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Updated

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Checkbox changes

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Invalidated

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Forget dependencies

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Recalculate

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Recalculate

Checkbox
Scatter
Plot
Slider
Dist Plot

Solution: Updated

Checkbox
Scatter
Plot
Slider
Dist Plot

Conclusion

Agenda

  • Reactivity overview

  • How do other frameworks work?

  • Reactive programming

  • Walking the graph

  • Your turn

  • Conclusion

Summary: reactive programming

  • Tell Shiny how each output should be filled
  • Trust that the framework will keep everything up-to-date
  • You’re setting the menu, not doing the cooking

Reactive programming