CITE THIS NOTEBOOK: Wolfram R&D LIVE: Principles of Dynamic Interfaces by Lou D'Andria. Wolfram Community JAN 12 2023.
The Wolfram Language includes a rich set of primitives for building user interfaces which look and behave in desirable ways. But the best way to combine those primitives to satisfy a particular interface goal is not always clear. In this talk, we’ll discuss how to utilize Dynamic and other primitives to build responsive and maintainable interfaces. We’ll pay special attention to progress indication and issues of synchronicity.
https://youtu.be/QFx5cnmG7CI

Talk Structure

We’ll outline some key principles to keep in mind while developing user interfaces in the Wolfram Language, and along the way highlight some essential concepts and key techniques that should be in every interface programmer’s toolkit.

Principles

• The Principle of Programmatic Generation
​

• The Principle of Minimal Dynamics
​

• The Principle of Maximum Encapsulation
​

• The Principle of Evaluation Blocking
​



The Principle of Programmatic Generation

Every interface should be generated by a program.

The language primitives

Dynamics and controls

Dynamic, DynamicWrapper, DynamicModule, …
Button, Checkbox, Slider, IntervalSlider, …
LocatorPane, EventHandler, …
guide/DynamicInteractivityLanguage
guide/ControlObjects

Layout and styling

Style, Panel, Framed, …
Grid, Row, Column, …
PaneSelector, Overlay, …
TabView, TableView, …
guide/UserInterfaceStructuringAndLayout

Deployment

Deploy, CloudDeploy, …
CreateDocument, CreatePalette, CreateDialog, …
DockedCells, AttachCell, …
guide/CustomInterfaceConstruction

Generated on demand

Manipulate
SystemInformation
WolframAlpha[]
Audio, Video, …
Iconize, Dataset, Summary boxes, …

Pre-generated

Palettes: About Box, Typesetting, Assistants, …
Dialogs: Preferences, Cloud Open / Save / Publish, Headers and Footers, …
Toolbars: Help Viewer, Presenter Tools, Multipurpose Bar, Wolfram|Alpha Notebook Edition, …
Contextual Interfaces: Drawing Tools, Image Editors, …

Dynamic wants to be current

The goal of Dynamic[expr] is to display expr as it is right now. And now. And now. You’re (almost) always looking at now.
Dynamic[x]
0
x=0.5;
Slider[Dynamic[x]]
When a Dynamic is evaluated for display, the kernel computes a full dependency graph.
Any change to any variable in that dependency graph triggers another update.
f[x_]:=g[x]+a;​​g[x_]:=h[x]+b;​​h[x_]:=x^2;
Dynamic[f[3]]
f[3]
a=2
2
g[x_]:=h[x]+2b

Dynamic really wants to be current

Dynamics that update too frequently are just as useless as dynamics that update too rarely.

When updates are too frequent

Restrict the scope of the Dynamic, either structurally, or via Refresh, TrackedSymbols, ControlActive, etc.
c=0;Dynamic[++c]
c=0;Dynamic[++c,TrackedSymbols{},UpdateInterval1]

When updates are too rare

Make sure the symbols you think should be triggering an update actually are involved in the Dynamic.
Dynamic[Now,TrackedSymbols{c}]
Fri 11 Sep 2026 20:16:28GMT-5
Slider[Dynamic[c]]
Or, you can always use UpdateInterval.
Dynamic[Now]
Fri 11 Sep 2026 20:16:28GMT-5
Dynamic[Now,UpdateInterval1]
Fri 11 Sep 2026 20:16:28GMT-5

Dynamic wants to be seen

Dynamic does nothing unless it is typeset and rendered by the front end.
Dynamic[var=456];
This doesn’t set the value of var.
Dynamic[var]
var
Neither does this.
CreateDocument[CellGroup[{TextCell["example section","Section"],ExpressionCell[Dynamic[var=123],"Output"]},Closed]];

Advanced tip: Avoid measuring unseen content

There are constructs (PaneSelector, Mouseover, TabView, OpenerView, MenuView, …) that hold several expressions, and only display one at a time.
TabView[99^{11,55,99}]
1
2
3
8953382542587164451099
But the front end needs to render every pane up front when ImageSize is All.
TabView[{1Dynamic[Echo["first pane"]],2Dynamic[Echo["second pane"]]},Dynamic[pane]]
1
2
first pane
»
second pane
»
second pane
»
first pane
»
first pane
»
inner:0
Use ImageSize  Automatic to avoid this.
TabView[{1Dynamic[Echo["first pane"]],2Dynamic[Echo["second pane"]]},Dynamic[pane],ImageSizeAutomatic]


The Principle of Minimal Dynamics

A Dynamic should never encompass unnecessary evaluation.

What is “unnecessary”?

Typical example of minimizing the scope of a Dynamic.

Wrap Dynamic around everything

Wrap Dynamic around fewer things

Wrap Dynamic around one thing

Nesting Dynamics

When nested, an inner Dynamic can update independently of whether outer Dynamics have been triggered. However, an outer Dynamic always force inner Dynamics to re-evaluate.

Avoiding Dynamics

Sometimes, it’s worth asking if Dynamics are really needed at all for a given task.

Notebook Programming

Notebooks are structured documents whose contents can be manipulated by Wolfram Language code.
◼
  • Buttons can overwrite themselves via EvaluationBox / BoxObject.
  • ◼
  • Construct a new notebook containing all cells from this notebook with a given cell tag.
  • ◼
  • Any other document gymnastics you can imagine…
  • 

    The Principle of Maximum Encapsulation

    Interfaces should require no unnecessary initialization and produce no unnecessary side effects.
    Two different solutions:
    ◼
  • Deploy the result of running the code. (About Box, Preferences, …)
  • ◼
  • Deploy the code itself, and run it on the user’s machine. (Manipulate, SystemInformation, …)
  • Use DynamicModule

    Scoping construct

    Local variables in one instance of your structure are automatically isolated from any other instances.
    This is what Manipulate uses.

    Saved state

    Variable values will be preserved across sessions.

    Initialization

    Initialization code can be included manually, or automatically, or both.

    SaveDefinitions

    SaveDefinitions is an option to Manipulate and DynamicModule which embeds a copy of all relevant definitions into the output (via FullDefinition).

    Passing variables by reference

    When producing interfaces via program, it can quickly become awkward to develop everything inside of a single DynamicModule.
    Here’s a more maintainable and extensible architecture, which doesn’t quite work…

    Why not?

    Each utility is only getting access to the value of the local symbol, not a (pre-evaluated) reference to the local symbol.

    Passing variables by reference

    This fixed code relies on the fact that Dynamic doesn’t evaluate its first argument.
    Using holding attributes would also allow passing variables by reference.
    

    The Principle of Evaluation Blocking

    Motivating example

    Analogy

    Imagine you’re in a grocery store with only two checkout lanes open:
    ◼
  • an express lane (which is not self-serve) if you have 6-or-fewer items, and
  • ◼
  • the main checkout lane for everyone else.
  • Personnel

    Now imagine there's only one person working at the store, Cornell, who is staffing both lanes according to some rules:
    ◼
  • If there is no customer in the express lane, Cornell takes care of customers in the main checkout lane.
  • ◼
  • If there are customers in the express lane, Cornell pauses work on the main checkout lane long enough to check them out.
  • ◼
  • If a customer in the express lane has more than 6 items, Cornell stops that checkout without finishing.
  • Dynamic

    ◼
  • By default, Dynamic[expr] is “synchronous” -- it will only run for about 6 seconds before timing out.
  • ◼
  • The front end stops doing everything else when waiting for a synchronous dynamic.
  • ◼
  • Dynamic[expr, SynchronousUpdating -> False] can take as long as it wants, without the front end stopping other processing.
  • ◼
  • SynchronousUpdating -> False uses the same evaluation queue as shift-enter.
  • Terminology

    Take home

    If you have more than six items, stay out of the express lane!

    Let slow things be slow

    Any evaluation that might take more than a few seconds

    Asking the user for blocking input

    Getting data from a network

    Rendering a complicated graphic or box structure

    Assembling an extensive report

    Showing progress

    What to do when you have a long running evaluation that you want to keep tabs on?

    Monitor

    See also: PrintTemporary, StatusArea, Annotation, …

    What’s really happening here?

    Synchronous dynamics can update during long-running queued evaluations.
    Note that synchronous dynamics will not update during preemptive evaluations.

    More Button examples

    ◼
  • Determinate progress indicators:
  • ◼
  • Indeterminate progress indicators:
  • ◼
  • However, this sample code is missing one important feature…
  • Fixed Button example

    It is especially important for interfaces to handle aborts without getting totally confused.

    EventHandler Method

    EventHandler also supports Method  “Queued”.
    And because Button uses EventHandler in Graphics, we can do things like this:

    Synchronous dynamics can trigger long evaluations

    Not many controls can directly run queued evaluations. Button, EventHandler, ActionMenu. That’s about it.
    Even though you can’t use a synchronous control to perform a long running evaluation, you can use a synchronous control to kick off a long-running evaluation, by having it trigger an asynchronous dynamic.

    Example

    ControlActive

    PerformanceGoal

    ControlActive

    When ControlActive appears in a dynamic that has SynchronousUpdating set to Automatic, then the draft renderings (1st argument) are done as preemptive evaluations, and the final rendering (2nd argument) uses a queued evaluation.

    Advanced example

    http://stackoverflow.com/questions/5087443/mathematica-asynchronous-incremental-generation-of-dynamical-graphics/

    PreemptProtect

    Todd Gayley’s Essay on preemptive evaluation
    http://mathematica.stackexchange.com/a/25829
    Read this to understand details of preemption, PreemptProtect, and preemption-safe code.

    Don’t be afraid to use the slow lane

    It’s there for a reason. There’s no shame in using it.
    Don’t change the DynamicEvaluationTimeout!

    Lots more examples…

    Wolfram Function Repository

    And the source code for every one of these functions is freely available!
    https://resources.wolframcloud.com/FunctionRepository/category/user-interface-construction
    Just a few examples of…
    ◼
  • Controls
  • ◼
  • Utilities
  • ◼
  • Complete interfaces
  • 

    Summary

    The Principle of Programmatic Generation

    Every interface should be generated by a program.

    The Principle of Minimal Dynamics

    A Dynamic should never encompass unnecessary evaluation.

    The Principle of Maximum Encapsulation

    Interfaces should require no unnecessary initialization and produce no unnecessary side effects.

    The Principle of Evaluation Blocking

    Only queued evaluations should ever block for user input. Most time-consuming evaluations should also be queued.