Advanced Dynamic Functionality

"Introduction to Manipulate" and "Introduction to Dynamic" provide most of the information you need to use the Wolfram Language's interactive features accessible through the functions (RefLink[Manipulate, paclet:ref/Manipulate]), (RefLink[Dynamic, paclet:ref/Dynamic]), and (RefLink[DynamicModule, paclet:ref/DynamicModule]). This tutorial gives further details on the workings of (RefLink[Dynamic, paclet:ref/Dynamic]) and (RefLink[DynamicModule, paclet:ref/DynamicModule]) and describes advanced features and techniques for achieving maximum performance for complex interactive examples.

Many examples in this tutorial display a single output value and use (RefLink[Pause, paclet:ref/Pause]) to simulate slow calculations. In real life, you will instead be doing useful computations and displaying sophisticated graphics or large tables of values.

Module versus DynamicModule

(RefLink[Module, paclet:ref/Module]) and (RefLink[DynamicModule, paclet:ref/DynamicModule]) have similar syntax and in many respects behave similarly, at least at first glance. They are, however, fundamentally different in such areas as when their variables are localized, where the local values are stored, and in what universe the variables are unique.

(RefLink[Module, paclet:ref/Module]) works by replacing all occurrences of its local variables with new, uniquely named variables, constructed so that they do not conflict with any variables in the current session of the Wolfram Language kernel.

You can see the names of these localized variables by allowing them to "escape" the context of the module without having been assigned a value:

Module[{x},x]

The local variables can be updated dynamically just like any other variables:

Module[{x},Dynamic[x]]

That is why sliders inside (RefLink[Module, paclet:ref/Module]) seem to work just as well as sliders inside (RefLink[DynamicModule, paclet:ref/DynamicModule]):

Table[Module[{x=.5},{Slider[Dynamic[x]],Dynamic[x]}],2]

Table[DynamicModule[{x=.5},{Slider[Dynamic[x]],Dynamic[x]}],2]

Both examples produce seemingly independent sliders that allow separate settings of separate copies of the variable x. The problem with sliders inside (RefLink[Module, paclet:ref/Module]) is that a different kernel session may coincidentally share the same localized variable names. So if this notebook is saved and then reopened sometime later, the sliders may "connect" to variables in some other (RefLink[Module, paclet:ref/Module]) that happen to have the same local variables at that time.

This will not happen with the sliders inside (RefLink[DynamicModule, paclet:ref/DynamicModule]) because (RefLink[DynamicModule, paclet:ref/DynamicModule]) waits to localize the variables until the object is displayed in the front end and generates local names that are unique to the current session of the front end. Localization happens when (RefLink[DynamicModule, paclet:ref/DynamicModule]) is first created as output and then repeats anew each time the file that contains (RefLink[DynamicModule, paclet:ref/DynamicModule]) is opened, so there can never be a name conflict among examples generated in different sessions.

Variables generated by (RefLink[Module, paclet:ref/Module]) are purely kernel session variables; when the kernel session ends, the values are irretrievably lost. (RefLink[DynamicModule, paclet:ref/DynamicModule]), on the other hand, generates a structure in the output cell that is responsible for maintaining the values of the variables, allowing them to be saved in files. This is a somewhat subtle concept, best explained by way of two analogies. First, you can think of (RefLink[DynamicModule, paclet:ref/DynamicModule]) as a sort of persistent version of (RefLink[Module, paclet:ref/Module]).

Consider this command:

Module[{x=2, y, z},
x=4;
y=(x^2);
x=8;
z=(x^3);
]

The module in this example evaluates a series of expressions in order, and from one line to the next the values of all the local module variables are preserved (obviously). You can have as many lines as you like in the compound expression, but they all have to be there at the start; once the (RefLink[Module, paclet:ref/Module]) has finished execution, it evaporates along with all its local variables.

(RefLink[DynamicModule, paclet:ref/DynamicModule]), on the other hand, creates an environment in which evaluations of expressions in (RefLink[Dynamic, paclet:ref/Dynamic]) that appear within the body of the (RefLink[DynamicModule, paclet:ref/DynamicModule]) are like additional lines in the compound expression in the previous example. From one dynamic update to the next the values of all the variables are preserved, just as if the separate evaluations were separate lines in a compound expression, all within the local variable context created by (RefLink[DynamicModule, paclet:ref/DynamicModule]).

This preservation of variable values extends not just to subsequent dynamic evaluations within the same session, but to all future sessions. Because all the local variable values are stored and preserved in the notebook file, if the notebook is opened in an entirely new session of the Wolfram System, the values will still be there, and dynamic updates will resume just where they left off. (RefLink[DynamicModule, paclet:ref/DynamicModule]) is like an indefinitely extendable (RefLink[Module, paclet:ref/Module]).

Another way to think about the difference between (RefLink[Module, paclet:ref/Module]) and (RefLink[DynamicModule, paclet:ref/DynamicModule]) is that while (RefLink[Module, paclet:ref/Module]) localizes its variables for a certain duration of time (while the body of the module is being evaluated), (RefLink[DynamicModule, paclet:ref/DynamicModule]) localizes its variables for a certain area of space in the output.

As long as that space of the output remains in existence, the values of the variables defined for it will be preserved, allowing them to be used in subsequent evaluations of (RefLink[Dynamic, paclet:ref/Dynamic]) expressions within the scope (area) of the (RefLink[DynamicModule, paclet:ref/DynamicModule]). Saving the output into a file puts that bit of real estate into hibernation, waiting for the moment when the file is opened again. (In computer science terms, this is sometimes referred to as a freeze-dried or serialized object.)

The ability of (RefLink[DynamicModule, paclet:ref/DynamicModule]) to preserve state across sessions is also a way of extending the notion of editing in a file. Normally when you edit text or expressions in a file, save the file, and reopen it, you expect it to open the way you left it. Editing means changing the contents of a file.

Ordinary kernel variables do not have this property; if you make an assignment to x, then quit and restart the Wolfram System, x does not have that value anymore. There are several reasons for this, not least of which is the question of where the value of x should be saved.

(RefLink[DynamicModule, paclet:ref/DynamicModule]) answers this question by defining a specific location (the output cell) where values of specific variables (the local variables) should be preserved. Arbitrary editing operations, like moving a slider, typing in an input field, or dragging a dynamic graphics object, change the values of the local variables. And since these values are automatically preserved when the file is saved, the sliders, and other objects, open exactly where they were left. Thus (RefLink[DynamicModule, paclet:ref/DynamicModule]) lets you make any quantity editable in the same way that text and expressions can be edited and saved in notebook files.

Front End Ownership of DynamicModule Variable Values

Ordinary variables in the Wolfram Language are owned by the kernel. Their values reside in the kernel, and when you ask the Wolfram System to display the value in the front end, a transaction is initiated with the kernel to retrieve the value. The same is true of dynamic output that refers to the values of ordinary variables.

Consider this example:

x=0;

Table[Slider[Dynamic[x]],500]

When one slider is moved, the other 499 move in sync with it. This requires 500 separate transactions with the kernel to retrieve the value of x. (The semantics of the Wolfram Language are complex enough that there is no guarantee that evaluating x several times in a row will actually return the same value each time: it would not be possible for the front end to improve efficiency by somehow sharing a single value retrieved from the kernel with all the sliders.)

Variables declared with (RefLink[DynamicModule, paclet:ref/DynamicModule]), on the other hand, are owned by the front end. Their values reside in the front end, and when the front end needs a value, it can be retrieved locally with very little overhead.

The following example thus runs noticeably faster:

DynamicModule[{x=0},Table[Slider[Dynamic[x]],500]]

If a complex function is applied to such a variable, its value must of course be sent to the kernel. This happens transparently, with each side of the system being kept informed on a just-in-time basis of any changes to variable values.

Whether it is better to use a normal kernel variable or a (RefLink[DynamicModule, paclet:ref/DynamicModule]) variable in a given situation depends on a number of factors. The most important is the fact that values of all (RefLink[DynamicModule, paclet:ref/DynamicModule]) variables are saved in the file when the notebook is saved. If you need a value preserved between sessions, it must be declared in a (RefLink[DynamicModule, paclet:ref/DynamicModule]). On the other hand, a temporary variable holding a large table of numbers, for example, might be a poor choice for a (RefLink[DynamicModule, paclet:ref/DynamicModule]) variable as it could greatly increase the size of the file. It is quite reasonable to nest a (RefLink[Module, paclet:ref/Module]) inside a (RefLink[DynamicModule, paclet:ref/DynamicModule]) and vice versa, or to partition variables between the front end and kernel.

In many situations the limiting factor in performance is the time needed to retrieve information from the kernel: by making variables local to the front end, speed can sometimes be increased dramatically.

Automatic Updates of Dynamic Objects

The specification for dynamic output is simple: (RefLink[Dynamic, paclet:ref/Dynamic])[expr] should always display the value you would get if you evaluated expr now. If a variable value, or some other state of the system, changes, the dynamic output should be updated immediately. Of course, for efficiency, not every dynamic output should be reevaluated every time any variable changes. It is critical that dependencies be tracked so that dynamic outputs are evaluated only when necessary.

Consider these two expressions:

Dynamic[a+b+c]

Dynamic[If[a, b, c]]

The first expression might change its value any time the value of a, b, or c changes, or if any patterns associated with a, b, or c are changed. The second expression depends on a and b (but not c) while a is (RefLink[True, paclet:ref/True]) and on a and c (but not b) while a is (RefLink[False, paclet:ref/False]). If a is neither (RefLink[True, paclet:ref/True]) nor (RefLink[False, paclet:ref/False]), then it depends only on a (because the (RefLink[If, paclet:ref/If]) statement returns unevaluated).

Figuring out these dependencies a priori is impossible (there are theorems to this effect), so instead the system keeps track of which variables or other trackable entities are actually encountered during the process of evaluating a given expression. Data is then associated with those variable(s) identifying which dynamic expressions need to be notified if the given variable receives a new value.

An important design goal of the system is to allow monitoring of variable values by way of dynamic output referencing them, without imposing any more load than absolutely necessary on the system, especially if the value of the variable is being changed rapidly.

Consider this simple example:

Dynamic[x]

Do[x,{x,1,5000000}]

When the dynamic output is created, it is evaluated, and the symbol x is tagged with information identifying the output that needs to be updated if its value should be changed.

When the loop is started and x is first given a new value, the data associated with it is consulted, and the front end is notified that the dynamic output needs to be updated. The data associated with x is then deleted. Essentially the system forgets all about the dynamic output, and subsequent assignments in the loop incur absolutely no speed penalty because of the existence of a dynamic output monitoring the value of x.

Much later (on a computer time scale; only a fraction of a second on a human time scale) when the screen is next redrawn and the dynamic output containing the reference to x is reevaluated, the connection between the dynamic output and the variable x is noticed again, and the association is reestablished.

Meanwhile the loop has continued to run. The next time the assignment is done after the screen is updated, another notification will be sent to the front end, and the process repeats.

By default, dynamic outputs triggered by changes in variable values are updated no faster than twenty times per second (this rate can be changed with the SystemOption "DynamicUpdateInterval"). In the previous example you will typically see the value jump by tens or hundreds of thousands with each update (more the faster your computer is), and the overall speed of the computation is slowed down by only a percent or two, nearly zero if you have a multiprocessor system.

You might expect that having a dynamic output monitoring the value of a symbol that is being changed rapidly in a tight loop would slow that loop down significantly. But the overhead is in fact zero-order in the rate at which the variable is changed, and in practice is usually minimal.

Dynamic outputs are only updated when they are visible on screen. This optimization allows you to have an open-ended number of dynamic outputs, all changing constantly, without incurring an open-ended amount of processor load. Outputs that are scrolled off-screen, above or below the current document position, will be left unexamined until the next time they are scrolled on-screen, at which point they are updated before being displayed. (Thus the fact that they stopped updating is not normally apparent, unless they have side effects, which is discouraged in general.)

Dynamic output can depend on things other than variables, and in these cases tracking is also done carefully and selectively.

This gives a rapidly updated display of the current mouse position in screen coordinates:

Dynamic[MousePosition[]]

As long as the output is visible on screen, there will be a certain amount of CPU activity any time the mouse is moved, because this particular dynamic output is being redrawn immediately with every movement of the mouse. But if it is scrolled off-screen, the CPU usage will vanish.

Refresh

Normally, dynamic output is updated whenever the system detects any reason to believe it might need to be (see "Automatic Updates of Dynamic Objects" for details about what this means). (RefLink[Refresh, paclet:ref/Refresh]) can be used to modify this behavior by specifying explicitly what should or should not trigger updates.

This updates when either slider is moved:

DynamicModule[{x,y},Column[{
Slider[Dynamic[x]],
Slider[Dynamic[y]],
Dynamic[{x,y}]}]]

(RefLink[Refresh, paclet:ref/Refresh]) with a (RefLink[TrackedSymbols, paclet:ref/TrackedSymbols]) option can be used to specify a list of those symbols that should be tracked, with all other reasons for updating being ignored.

This updates only when x changes, ignoring changes in y:

DynamicModule[{x,y},Column[{
Slider[Dynamic[x]],
Slider[Dynamic[y]],
Dynamic[Refresh[{x,y},TrackedSymbols->{x}]]}]]

When you move the second (y) slider, nothing happens, but when you move the first slider, the expression is updated to reflect the current value of both variables. You might say that after moving the second slider, the dynamic output is wrong, since it does not reflect the current state of the system. But that is essentially the whole reason for the existence of the (RefLink[Refresh, paclet:ref/Refresh]) command. It allows you to override the system's mandate to always update dynamic output any time it is potentially out of date.

The setting (RefLink[TrackedSymbols, paclet:ref/TrackedSymbols])->(RefLink[Automatic, paclet:ref/Automatic]) can be used to track only those symbols that occur explicitly (lexically) in the expression given in the first argument to (RefLink[Refresh, paclet:ref/Refresh]). For example, if you use a function that depends on a global variable that does not occur lexically inside (RefLink[Refresh, paclet:ref/Refresh]), changes to the value of the global variable will not cause updating, when normally they would.

(RefLink[Refresh, paclet:ref/Refresh]) can also be used to cause updates at regular time intervals. It is important to understand that this is not a feature that should be used lightly. It is fundamental to the design of (RefLink[Dynamic, paclet:ref/Dynamic]) that it does not need to update on any fixed schedule, because it simply always updates immediately whenever doing so would be useful. But there are some situations where this either cannot, or just unfortunately does not, happen.

One potentially vexing case is (RefLink[RandomReal, paclet:ref/RandomReal]). Every time you evaluate (RefLink[RandomReal, paclet:ref/RandomReal])[], you get a different answer, and you might think that (RefLink[Dynamic, paclet:ref/Dynamic])[(RefLink[RandomReal, paclet:ref/RandomReal])[]] should therefore constantly update itself as fast as possible. But this would normally not be useful, and would in fact have negative consequences for a number of algorithms that use randomness internally (e.g., a Monte Carlo integration inside (RefLink[Dynamic, paclet:ref/Dynamic]) should probably not update constantly simply because it will, in fact, give a slightly different answer each time).

For this reason, (RefLink[RandomReal, paclet:ref/RandomReal])[] is not "ticklish", in the sense that it does not trigger updates. If you want to see new random numbers, you have to use (RefLink[Refresh, paclet:ref/Refresh]) to specify how frequently you want the output updated. Another example of non-ticklish functions are file system operations.

This gives you a new number every second:

Dynamic[Refresh[RandomReal[],UpdateInterval->1]]

This is not updated automatically:

Dynamic[FileByteCount[ToFileName[{$InstallationDirectory,"SystemFiles","FrontEnd","Palettes"},"ClassroomAssistant.nb"]]]

In the unlikely event that the file containing the Classroom Assistant palette changes size, this (RefLink[Dynamic, paclet:ref/Dynamic]) will not be updated. If you want to monitor the size of a file, you need to use (RefLink[Refresh, paclet:ref/Refresh]) to specify a polling interval. (On sufficiently advanced operating systems it would theoretically be possible for the Wolfram Language to efficiently receive notifications of file system activity, and future versions of the Wolfram Language might in fact update such expressions automatically. As with other (RefLink[Dynamic, paclet:ref/Dynamic]) expressions, automatic correctness is always the goal.)

Finally, several functions you might think would trigger dynamic updates in fact do not: for example, (RefLink[DateList, paclet:ref/DateList]) and (RefLink[AbsoluteTime, paclet:ref/AbsoluteTime]). As with (RefLink[RandomReal, paclet:ref/RandomReal]), it would cause more trouble than it is worth for these functions to automatically trigger updates, and (RefLink[Refresh, paclet:ref/Refresh]) can trivially be used to create clock-like objects. The function (RefLink[Clock, paclet:ref/Clock]) is intended specifically as a time-based function that is ticklish.

This updates approximately every second:

Dynamic[Refresh[DateList[],UpdateInterval->1]]

This updates without an explicit (RefLink[Refresh, paclet:ref/Refresh]):

Dynamic[Clock[{1,10}]]

Nesting Refresh

In the "Refresh" section examples, (RefLink[Refresh, paclet:ref/Refresh]) is always the outermost function inside (RefLink[Dynamic, paclet:ref/Dynamic]). You might almost wonder why its options are not simply options to (RefLink[Dynamic, paclet:ref/Dynamic]). But in fact it is often important to place (RefLink[Refresh, paclet:ref/Refresh]) as deeply in the expression as possible, especially if it specifies a time-based updating interval.

Consider this example:

DynamicModule[{showclock=True},{Checkbox[Dynamic[showclock]],Dynamic[If[showclock,Refresh[DateList[],UpdateInterval->0.05],"No clock"]]}]

When the checkbox is checked, (RefLink[Refresh, paclet:ref/Refresh]) is causing frequent updating of the clock, and CPU time is being consumed to keep things up-to-date. When the checkbox is unchecked, however, the (RefLink[Refresh, paclet:ref/Refresh]) expression is no longer reached by evaluation, the output remains static, and no CPU time is consumed. If (RefLink[Refresh, paclet:ref/Refresh]) were wrapped around the whole expression inside (RefLink[Dynamic, paclet:ref/Dynamic]), CPU time would be consumed constantly, even if the clock were not being displayed. The words "No clock" would be constantly refreshed, pointlessly. (This refreshing is not visible; there is no flicker of the screen, but CPU time is being consumed nevertheless.)

Nesting Dynamic

(RefLink[Dynamic, paclet:ref/Dynamic]) expressions can be nested, and the system takes great care to update them only when necessary. Particularly when the contents of a (RefLink[Dynamic, paclet:ref/Dynamic]) contain further interactive elements, it is important to keep track of what will stay static and what will update, when a given variable is changed.

Consider this example:

DynamicModule[{n=5,data=Table[RandomReal[],20]},
Column[{
Slider[Dynamic[n],{1,20,1}],Dynamic[Column[Table[With[{i=i},Slider[Dynamic[data[[i]]]]],{i,n}]]]}]]

The position of the first slider determines the number of sliders underneath it, and each of those sliders in turn is connected to the value of one element of a list of data. Because the number of sliders is variable, and changes dynamically in response to the position of the first slider, the table that generates them needs to be inside (RefLink[Dynamic, paclet:ref/Dynamic]).

The example works, but now suppose you want to display the value of each number in the list next to its slider.

You might at first try this:

DynamicModule[{n=5,data=Table[RandomReal[],20]},
Column[{
Slider[Dynamic[n],{1,20,1}],
Dynamic[Grid[Table[With[{i=i},
{Slider[Dynamic[data[[i]]]],data[[i]]}],{i,n}]
]]}]]

Now any time you click one of the lower sliders, it moves only one step, then stops. The problem is that the data[[i]] expressions in the second column of the grid are creating a dependency in the outer (RefLink[Dynamic, paclet:ref/Dynamic]) on the values in data.

As soon as data changes, the contents of the outer (RefLink[Dynamic, paclet:ref/Dynamic]), including the slider you are trying to drag, are destroyed and replaced with a nearly identical copy (in which the displayed value of one of the data[[i]] has been changed). In other words, the act of dragging the slider destroys it, preventing any further activity.

The solution to this is to prevent the outer (RefLink[Dynamic, paclet:ref/Dynamic]) from depending on the value of data, by making sure that all occurrences of data in the expression are wrapped in (RefLink[Dynamic, paclet:ref/Dynamic]):

DynamicModule[{n=5,data=Table[RandomReal[],20]},
Column[{
Slider[Dynamic[n],{1,20,1}],
Dynamic[Grid[Table[With[{i=i},
{Slider[Dynamic[data[[i]]]],Dynamic[data[[i]]]}],{i,n}]
]]}]]

Now you can drag any of the sliders and see dynamically updated values. This works because the outer (RefLink[Dynamic, paclet:ref/Dynamic]) now depends only on the value of n, the number of sliders, not on the value of data. (Technically this is because (RefLink[Dynamic, paclet:ref/Dynamic]) is (RefLink[HoldFirst, paclet:ref/HoldFirst]): when it is evaluated, the expression in its first argument is never touched by evaluation, and therefore no dependencies are registered.)

When building large, complex interfaces using multiple levels of nested (RefLink[Dynamic, paclet:ref/Dynamic]) expressions, these are important issues to keep in mind. The Wolfram Language works hard to do exactly the right thing even in the most complex cases. For example, the output of (RefLink[Manipulate, paclet:ref/Manipulate]) consists of a highly complex set of interrelated and nested (RefLink[Dynamic, paclet:ref/Dynamic]) expressions: if the dependency tracking system did not work correctly, (RefLink[Manipulate, paclet:ref/Manipulate]) would not work right.

Synchronous versus Asynchronous Dynamic Evaluations

The Wolfram System consists of two separate processes, the front end and the kernel. These really are separate processes in the computer science sense of the word: two independent threads of execution with separate memory spaces that show up separately in a CPU task monitor.

The front end and kernel communicate with each other through several Wolfram Symbolic Transfer Protocol (WSTP) connections, known as the main link, the preemptive link, and the service link. The main and preemptive links are pathways by which the front end can send evaluation requests to the kernel, and the kernel can respond with results. The service link works in reverse, with the kernel sending requests to the front end.

The main link is used for Shift+MacOSXReturnEnter evaluations. The front end maintains a queue of pending evaluation requests to send down this link. When you use Shift+MacOSXReturnEnter on one or more input cells, they are all added to the queue, and then processed one by one. At any one time, the kernel is only aware of a single main link evaluation, the one it is currently working on (if any). In the meantime, the front end remains fully functional; you can type, open and save files, and so on. There is no arbitrary limit on how long a main link evaluation can reasonably take. People routinely do evaluations that take days to complete.

The preemptive link works the same way as the main link in the sense that the front end can send an evaluation to it and get an answer, but it is administered quite differently on both ends. On the front end side, the preemptive link is used to handle normal (RefLink[Dynamic, paclet:ref/Dynamic]) updates. There is no queue; instead, the front end sends one evaluation at a time and waits for the result before continuing with its other work. It is thus important to limit preemptive link evaluations to a couple of seconds at most. During any preemptive link evaluation, the front end is completely locked up, and no typing or other actions are possible.

On the kernel side, evaluation requests coming from the preemptive link are given priority over evaluations from the main link, including the current running main link evaluation (if any). If an evaluation request comes from the preemptive link while the kernel is processing a main link evaluation, the main link evaluation is halted at a safe point (usually within microseconds). The preemptive link evaluation is then run to completion, after which the main link evaluation is restarted and allowed to continue as before. The net effect is similar to, though not the same as, a threading mechanism. Multiple fast preemptive link evaluations can be executed during a single long, slow main link evaluation, giving the impression that the kernel is working on more than one problem at a time.

Preemptive link evaluations can change the values of variables, including those being used by a main link evaluation running at the same time. There is no paradox here, and the interleaving is done in a way that is entirely safe, though it can result in some fairly peculiar behavior until you understand what is going on.

For example, evaluate this to get a slider:

Slider[Dynamic[x]]

Then evaluate this command, and during the 10 seconds it takes to finish, drag the slider around randomly:

Table[Pause[1];x,10]

You will not see anything happening (other than the slider moving) but when the second evaluation finishes, you will see that it has recorded 10 different values of x, representing the positions the slider happened to be at during the 10 points at which x was evaluated to build the list.

(RefLink[Dynamic, paclet:ref/Dynamic]) normally uses the preemptive link for its evaluations. Evaluation is synchronous, and the front end locks up until it is finished. This is unavoidable in some cases, but can be suboptimal in others. By setting the option (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[False, paclet:ref/False]), you can tell the front end to use the main link queue, rather than the preemptive link. The front end then displays a gray box placeholder until it receives the response from the kernel.

In this case, the default (synchronous) update is appropriate because the front end needs to know the result of evaluating the (RefLink[Dynamic, paclet:ref/Dynamic])[x] for drawing with the correct font size:

DynamicModule[{x=12},{Slider[Dynamic[x],{10,100}],Style["Hello",FontSize->Dynamic[x]]}]

Here, the output cell is drawn before the second dynamic expression finishes. A gray box placeholder persists for one second until the result is known. Reevaluate the example to see the gray box again:

DynamicModule[{n=1},Column[{Slider[Dynamic[n],{1,10}],Dynamic[Pause[n];n,SynchronousUpdating->False]}]]

Clicking the slider will update the display with a delay of between one and ten seconds. Notice that the cell bracket is outlined, just as if the cell were being Shift+MacOSXReturnEnter evaluated. This is an indication that the evaluation is queued, and that you can continue with other work in the front end while the evaluation is progressing.

Asynchronous updating is useful for displaying full (RefLink[Dynamic, paclet:ref/Dynamic]) subexpressions when it is possible to draw a screen around them and fill in their value later, in much the same way a web browser draws text around an image that is inserted later when it finishes downloading.

Why not always use asynchronous (RefLink[Dynamic, paclet:ref/Dynamic]) expressions? There are several reasons. First, they are queued so that, by definition, they do not operate while another Shift+MacOSXReturnEnter evaluation is underway. This is not the case for normal (synchronous) updates.

A synchronous (RefLink[Dynamic, paclet:ref/Dynamic]) updates smoothly even if the (RefLink[Pause, paclet:ref/Pause]) command above is running:

Pause[20]

DynamicModule[{n=1},Column[{Slider[Dynamic[n],{1,10}],Dynamic[n]}]]

Also, many controls need to be synchronous in order to be responsive to mouse actions. Making them asynchronous may cause potentially strange interactions with other controls.

Here is a problematic example:

n=1;
Column[{Slider[Dynamic[n],{1,10}],Dynamic[Graphics[Line[Table[{x,Sin[n x]},{x,0,2Pi,0.0001}]]],SynchronousUpdating->False]}]

Move the slider around rapidly, and you will end up with a choppy, distorted sine wave, because the value of n changed during the evaluation of the (RefLink[Table, paclet:ref/Table]) command. This is the correct, expected behavior, but it is probably not what you wanted.

This problem does not occur if you use synchronous (RefLink[Dynamic, paclet:ref/Dynamic]) expressions, generally does not happen with (RefLink[DynamicModule, paclet:ref/DynamicModule]) local variables, and can be avoided by storing the value of any potentially changing variables into a second variable before starting the asynchronous evaluations.

This fixes the problem:

n=1;
Column[{Slider[Dynamic[n],{1,10}],Dynamic[Module[{n1=n},Graphics[Line[Table[{x,Sin[n1 x]},{x,0,2Pi,0.0001}]]]],SynchronousUpdating->False]}]

ControlActive and SynchronousUpdating->Automatic

As a general rule, if you have a (RefLink[Dynamic, paclet:ref/Dynamic]) that is meant to respond interactively to the movements of a slider or other continuous-action control, it should be able to evaluate in under a second, preferably well under. If the evaluation takes longer than that, you are not going to get satisfactory interactive performance, whether the (RefLink[Dynamic, paclet:ref/Dynamic]) is updating synchronously or asynchronously.

But what if you have an example that simply cannot finish evaluating fast enough, yet you want to be able to make it respond to a slider? One option is to use asynchronous updating and simply accept that you will not get real-time interactive performance. If that is what you want to do, setting (RefLink[ContinuousAction, paclet:ref/ContinuousAction])->(RefLink[False, paclet:ref/False]) in the slider or other control is a good idea; that way you get only one update after the control is released, avoiding the starting up of potentially lengthy evaluations in the middle of a drag, before you have arrived at the value you want to stop at.

The cell bracket becomes outlined, indicating evaluation activity, only after you release the slider:

DynamicModule[{n=1},Column[{Slider[Dynamic[n],{1,10},ContinuousAction->False],Dynamic[Pause[n];n,SynchronousUpdating->False]}]]

Another, much better solution is to provide a fast-to-compute preview of some sort during the interactive control dragging operation, then compute the full, slow output when the control is released. Several features exist specifically to support this.

The first is the function (RefLink[ControlActive, paclet:ref/ControlActive]), which returns its first argument if a control is currently being dragged, and its second argument if not. Unlike (RefLink[Dynamic, paclet:ref/Dynamic]), (RefLink[ControlActive, paclet:ref/ControlActive]) is an ordinary function that evaluates in the kernel, returning one or the other of its arguments immediately. It can be embedded inside functions or option values.

The second feature is an option setting (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[Automatic, paclet:ref/Automatic]) for (RefLink[Dynamic, paclet:ref/Dynamic]), which makes the (RefLink[Dynamic, paclet:ref/Dynamic]) synchronous when a control is being dragged, and asynchronous when the control is released. Together, these two features can be used to implement a fast, synchronously updated display to be used while a control is being dragged, along with a slower, asynchronously updated display when it is released.

The displayed text changes depending on whether or not the slider is being dragged:

DynamicModule[{n=1},Column[{Slider[Dynamic[n],{1,10}],Dynamic[{n,ControlActive["Active","Not Active"]}]}]]

A simple number is displayed, synchronously, while the slider is being dragged, and when it is released, a graphic is generated asynchronously:

DynamicModule[{n=3},Column[{Slider[Dynamic[n],{3,1000,1}],Dynamic[Graphics[ControlActive[Inset[n,{0,0}],Line[Table[{{0,0},{Cos[t],Sin[t]}},{t,0.,2Pi,2Pi/n}]]],ImageSize->300,PlotRange->1],SynchronousUpdating->Automatic]}]]

This example shows that the front end can remain responsive no matter how long the final display takes to compute and that the preview and the final display can be completely different.

Of course, in most cases, you will want a preview that is some kind of reduced, thinned out, skeletal, or other elided form of the final display. Then the crude form can be fast enough to give a smooth preview, and the computation of the final version, even if it takes awhile, does not block the front end. In fact, this behavior is so useful that it is the default in (RefLink[Plot3D, paclet:ref/Plot3D]) and other plotting functions.

This displays a 3D plot with a very small number of plot points while the control is being dragged and then refines the image with a large number of plot points when the control is released:

DynamicModule[{n=1},Column[{Slider[Dynamic[n],{1,5}],Dynamic[Plot3D[Sin[n x y],{x,0,3},{y,0,3},PlotPoints->ControlActive[10,100],MaxRecursion->0],SynchronousUpdating->Automatic]}]]

By default, (RefLink[Plot3D, paclet:ref/Plot3D]) produces a similar preview, though with a somewhat less extreme spread of quality:

DynamicModule[{n=1},Column[{Slider[Dynamic[n],{1,5}],Dynamic[Plot3D[Sin[n x y],{x,0,3},{y,0,3}],SynchronousUpdating->Automatic]}]]

In addition, (RefLink[Manipulate, paclet:ref/Manipulate]) uses (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[Automatic, paclet:ref/Automatic]) in (RefLink[Dynamic, paclet:ref/Dynamic]) by default so the example becomes as simple as it can be:

Manipulate[Plot3D[Sin[n x y],{x,0,3},{y,0,3}],{n,1,5}]

You may have noticed one subtlety. When the output of either of the above three examples is first placed in the notebook, you see a crudely drawn (control-active state) version, followed shortly thereafter by a refined (control-inactive) version. This is intentional: the system is providing a fast preview so you see something rather than just a gray rectangle. The first update is done synchronously, just as if a control were being dragged.

This preview-evaluation behavior is examined in more detail in the next section.

ImageSizeCache in Dynamic

ImageSizeCache is an option to (RefLink[Dynamic, paclet:ref/Dynamic]) that specifies a rectangular size to be used in displaying a (RefLink[Dynamic, paclet:ref/Dynamic]) whose value has not yet been computed. It is normally not specified in input, but is instead generated automatically by the front end and saved in files along with the (RefLink[Dynamic, paclet:ref/Dynamic]) expression.

The interaction of (RefLink[ControlActive, paclet:ref/ControlActive]), (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating]), and ImageSizeCache is subtle, complex, and very useful. The first two constructs are explained in "ControlActive and SynchronousUpdating->Automatic". The remaining part is explained here.

Note first that (RefLink[Dynamic, paclet:ref/Dynamic]) expressions with the default value of (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[True, paclet:ref/True]) will never have a chance to use the value of their ImageSizeCache option, because they are always computed before being displayed, and, once computed, the actual image size will be used.

On the other hand, (RefLink[Dynamic, paclet:ref/Dynamic]) expressions with (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[False, paclet:ref/False]) will be displayed as a gray rectangle while they are being computed for the first time. In that case, the size of the rectangle is determined by the value of the ImageSizeCache option. This allows the surrounding contents of the notebook to be drawn in the right place, so that when the (RefLink[Dynamic, paclet:ref/Dynamic]) finishes updating, there is no unnecessary flicker and shifting around of the contents of the notebook. (Users of HTML will recognize this as the analog of the width and height parameters of the img tag.)

It is generally not necessary to specify the ImageSizeCache option explicitly, because the system will set it automatically as soon as the value of the (RefLink[Dynamic, paclet:ref/Dynamic]) is computed successfully. (The computed result is measured, and the actual size copied into the ImageSizeCache option.) This automatically computed value is preserved if the (RefLink[Dynamic, paclet:ref/Dynamic]) output is saved in a file.

Consider the following input:

Dynamic[Pause[3];Style["Hello",100],SynchronousUpdating->False]

When the input expression is evaluated, a small gray rectangle appears; because this (RefLink[Dynamic, paclet:ref/Dynamic]) has never been evaluated, there is no cache of its proper image size, and a default small size is used.

Three seconds later, the result arrives, and the dynamic output is displayed. At this point an actual size is known, and is copied to the ImageSizeCache option. You can see the value by clicking anywhere in the output cell and choosing (MenuGrayLink[Show Expression, paclet:ref/menuitem/ShowExpression]) from the (MenuGrayLink[Cell, paclet:guide/CellMenu]) menu. (This shows you the underlying expression representing the cell, exactly as it would appear in the notebook file if you were to save this cell.) Note the presence of an ImageSizeCache option.

Now type a space in some innocuous place in the raw cell expression (to force a reparsing of the cell contents), and choose (MenuGrayLink[Show Expression, paclet:ref/menuitem/ShowExpression]) again to reformat the cell. This time you will see a gray rectangle the size of the final output for three seconds, followed by the proper output. This is also what you would see if you opened a notebook containing previously saved, asynchronous dynamic output.

The behavior of the setting (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[Automatic, paclet:ref/Automatic]) is similar, but subtly different. As we saw in the examples in "ControlActive and SynchronousUpdating->Automatic", with the (RefLink[Automatic, paclet:ref/Automatic]) setting, a synchronous preview-evaluation is done when the output is first placed, to provide a (hopefully) rapid display of the contents of the (RefLink[Dynamic, paclet:ref/Dynamic]) expression before the slower, asynchronous value is computed. Because the first evaluation is synchronous, no gray rectangle is ever displayed.

But this preview evaluation is done only if the ImageSizeCache option is not present. A (RefLink[Dynamic, paclet:ref/Dynamic]) with (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[Automatic, paclet:ref/Automatic]) and an ImageSizeCache option specifying explicit dimensions will not do a synchronous preview evaluation, and will instead display a gray rectangle (of the correct size) pending the result of the first asynchronous evaluation.

This may seem like baffling behavior at first, until you consider the practical effect of it. Generally speaking, (RefLink[Dynamic, paclet:ref/Dynamic]) expressions will always have an ImageSizeCache option (created automatically by the front end) except for the very first time they appear, when they are originally placed as output from an evaluation. Any time they are opened from a file they will have a known, cached size.

In (RefLink[Manipulate, paclet:ref/Manipulate]), which accounts for the vast majority of dynamic outputs, the default setting is (RefLink[SynchronousUpdating, paclet:ref/SynchronousUpdating])->(RefLink[Automatic, paclet:ref/Automatic]) and the described behavior lets the output show up cleanly with a preview image in place when it is first generated. When a file containing dozens of (RefLink[Manipulate, paclet:ref/Manipulate]) outputs is opened, you will get a useful behavior that is familiar from web browsers: the text displays immediately, and graphics (and other dynamic content) fill in later as fast as they are able. So you can scroll through a file rapidly, without any delay associated with precomputing potentially many preview images before the first page of the file can be displayed.

If the initial evaluations when the (RefLink[Manipulate, paclet:ref/Manipulate]) output was first placed were not synchronous, there would be flicker and resizing/shifting of the surroundings, because the size would not be known. But when the (RefLink[Manipulate, paclet:ref/Manipulate]) output is opened from a file, the size is known, and the final output can be placed smoothly without flicker.

One-Sided Updating of ControlActive

After evaluating in the kernel, (RefLink[ControlActive, paclet:ref/ControlActive]) can trigger an update of the (RefLink[Dynamic, paclet:ref/Dynamic]) containing it, but in a highly asymmetric fashion, only when it is going from the active to the inactive state. When making a transition in the other direction, from inactive to active, (RefLink[ControlActive, paclet:ref/ControlActive]) does not trigger any update on its own.

The reason for this somewhat unusual behavior is that (RefLink[ControlActive, paclet:ref/ControlActive]) is a completely global concept. It returns the active state if any control anywhere in the Wolfram System is currently being dragged—even controls that have nothing to do with a particular (RefLink[Dynamic, paclet:ref/Dynamic]) that happen to contain a reference to (RefLink[ControlActive, paclet:ref/ControlActive]). If (RefLink[ControlActive, paclet:ref/ControlActive]) caused updates on its own, then as soon as you clicked any control, all (RefLink[Dynamic, paclet:ref/Dynamic]) expressions containing references to (RefLink[ControlActive, paclet:ref/ControlActive]) (e.g., a default dynamic (RefLink[Plot3D, paclet:ref/Plot3D]) output) would immediately update, which would be entirely pointless. Instead, only those outputs that have some other reason for updating will pick up the current value of (RefLink[ControlActive, paclet:ref/ControlActive]).

On the other hand, when the control is released, it is desirable to fix up any outputs that were drawn in control-active form, to give them their final polished appearance. Thus, when (RefLink[ControlActive, paclet:ref/ControlActive]) is going into its inactive state, it needs to, on its own, issue updates to any (RefLink[Dynamic, paclet:ref/Dynamic]) expression that may have been drawn in the active state.

Dragging the slider does not change the Active/Inactive display because (RefLink[ControlActive, paclet:ref/ControlActive]) does not trigger updates on its own:

DynamicModule[{x},{Slider[Dynamic[x]],Dynamic[ControlActive["Active","Inactive"]]}]

This Active/Inactive display updates because x in the dynamic output changes:

DynamicModule[{x},{Slider[Dynamic[x]],Dynamic[{x,ControlActive["Active","Inactive"]}]}]

Watch carefully what happens when you click the slider. If you click and hold the mouse without moving it, the display will remain (RefLink[Inactive, paclet:ref/Inactive]). But as soon as you move it, the display updates to Active. This is happening because x changed, causing the (RefLink[Dynamic, paclet:ref/Dynamic]) as a whole to update, thus picking up the current state of (RefLink[ControlActive, paclet:ref/ControlActive]).

Now carefully release the mouse button without moving the mouse. Note that the display does revert to (RefLink[Inactive, paclet:ref/Inactive]) even though x has not changed.

DynamicModule Wormholes

The variables declared in a (RefLink[DynamicModule, paclet:ref/DynamicModule]) are localized to a particular rectangular area within one cell in a notebook. There are situations in which it is desirable to extend the scope of such a local variable to other cells or even other windows. For example, you might want to have a button in one cell that opens a dialog box that allows you to modify the value of a variable declared in the same scope as the button that opened the dialog.

This can be done with one of the more surreal constructs in the Wolfram Language, a (RefLink[DynamicModule, paclet:ref/DynamicModule]) wormhole. (RefLink[DynamicModule, paclet:ref/DynamicModule]) accepts the option DynamicModuleParent, whose value is a NotebookInterfaceObject that refers to another (RefLink[DynamicModule, paclet:ref/DynamicModule]) anywhere in the front end. For purposes of variable localization, the (RefLink[DynamicModule, paclet:ref/DynamicModule]) with this option will be treated as if it resided inside the one referred to, regardless of where the two actually are (even if they are in separate windows).

The tricky part in setting up such a wormhole is getting the NotebookInterfaceObject necessary to refer to the parent (RefLink[DynamicModule, paclet:ref/DynamicModule]). This reference can be created only after the (RefLink[DynamicModule, paclet:ref/DynamicModule]) has been created and placed as output, and it is valid only for the current session.

To make the process easier, and in fact avoid all reference to explicit NotebookInterfaceObjects, (RefLink[DynamicModule, paclet:ref/DynamicModule]) also accepts the option (RefLink[InheritScope, paclet:ref/InheritScope]), which automatically generates the correct value of the DynamicModuleParent option to make the new (RefLink[DynamicModule, paclet:ref/DynamicModule]) function as if it were inside the scope of the (RefLink[DynamicModule, paclet:ref/DynamicModule]) from which it was created. This is confusing, so an example is in order.

Evaluate this to create an output with a + button and a number:

DynamicModule[{x=1},{Button["+",++x],Button["Make - Palette",CreatePalette[DynamicModule[{},Button["-",--x],InheritScope->True]]],Dynamic[x]}]

Clicking the + button increments the value of a (RefLink[DynamicModule, paclet:ref/DynamicModule]) local variable, which is displayed at the end of the output. To decrement the number you have to click the Make - Palette button, which creates a new (very small) floating palette window containing a - button.

This - button is living in a wormhole created by the (RefLink[InheritScope, paclet:ref/InheritScope]) option of the (RefLink[DynamicModule, paclet:ref/DynamicModule]) containing it. Clicking the button decrements the value of a local, private variable in the scope of a distant (RefLink[DynamicModule, paclet:ref/DynamicModule]) in another window.

(RefLink[InheritScope, paclet:ref/InheritScope]) can be used only when the code creating the second (RefLink[DynamicModule, paclet:ref/DynamicModule]) is executed from inside a button or other dynamic object located within the first (RefLink[DynamicModule, paclet:ref/DynamicModule]). By using DynamicModuleParent explicitly, it is possible to link up an arbitrary existing (RefLink[DynamicModule, paclet:ref/DynamicModule]), but doing so is tricky, and beyond the scope of this document.