# Effect of Block[] on iterators in Manipulate[]

The following is a toy example that hopefully shows the problem clearly enough.

Why does the following code create a nice, manipulable output:

simulationOutput = {1337, 2337, 30, 3337};
Clear[tmax]
{irrelevantOutput1, irrelevantOutput2, tmax, irrelevantOutput3} = simulationOutput;
Manipulate[
Plot[t^2, {t, startTime, endTime}],
{startTime, Manipulator[Dynamic[startTime, (startTime = Min[tmax - 1, #];
endTime = Max[endTime, Min[# + 1, tmax]]) &], {0, tmax}] &},
{endTime, Manipulator[Dynamic[endTime, (endTime = Max[1, #];
startTime = Min[startTime, Max[0, # - 1]]) &], {0, tmax}] &},
Initialization :> ({startTime, endTime} = {0, 1})]


But this (almost identical) code, with the additional Block[],

simulationOutput = {1337, 2337, 30, 3337};
Clear[tmax]
Block[{irrelevantOutput1, irrelevantOutput2, tmax, irrelevantOutput3},
{irrelevantOutput1, irrelevantOutput2, tmax, irrelevantOutput3} = simulationOutput;
Manipulate[
Plot[t^2, {t, startTime, endTime}],
{startTime, Manipulator[Dynamic[startTime, (startTime = Min[tmax - 1, #];
endTime = Max[endTime, Min[# + 1, tmax]]) &], {0, tmax}] &},
{endTime, Manipulator[Dynamic[endTime, (endTime = Max[1, #];
startTime = Min[startTime, Max[0, # - 1]]) &], {0, tmax}] &},
Initialization :> ({startTime, endTime} = {0, 1})]]


result in this, un-manipulate-able output?

If you're interested, the background behind my question is as follows. I have a simulation of a system of oscillators. The behavior of this system is then studied by providing initial conditions, then using NDSolve to find the behavior from t=0 to t=tmax. The output of the simulation (as simulationOutput) is then fed into a function (of which the following is a simplified example) so that I can see the results - this is the reason why I'm limiting the range of times in which the startTime and endTime can vary in to keep the values in the range of the InterpolatingFunction.

-

What Block does is to change the values of the existing global values for the time its body is evaluated. In your example because Manipulate has attributes HoldAll that means all arguments of the Manipulate don't evalute during evaluation of that Block's body and the Manipulate with unevaluated content is returned from the Block and sent to the FrontEnd for rendering.

Only in the process of rendering the Manipulate its content is sent from the FrontEnd to the Kernel for another evaluation and that then doesn't know anything about the Blocked values during the original evaluation anymore, which is why your code doesn't work as expected.

You can use Module instead of Block and everything will work as intended, at least as a first impression. But what you then do is to actually create new symbols with every call that will survive and will aggregate memory which might become a problem if that's done often. You could solve that by cleaning them up with a Deinitialization when the Manipulate is deleted, but that might have some issues (it's not exactly easy to understand if and when exactly such a deinitialization is executed, the documentation is vague and experiments don't help much to understand these details).

As long as the values of those local variables are small the best solution is to use DynamicModule (or additional Manipulate-variables without controlers) to store that data. If these values become large in memory size, you'll suffer from the extra effor of moving that data from Kernel to FrontEnd and back, though. Here is how that could look like:

Manipulate[
Plot[t^2, {t, startTime, endTime}],
{
startTime,
Manipulator[Dynamic[startTime,(
startTime = Min[tmax - 1, #];
endTime = Max[endTime, Min[# + 1, tmax]]
) &], {0, tmax}] &
},{
endTime,
Manipulator[Dynamic[endTime, (
endTime = Max[1, #];
startTime = Min[startTime, Max[0, # - 1]]
) &], {0, tmax}] &
},
{irrelevantOutput1, None},
{irrelevantOutput2, None},
{tmax, None},
{irrelevantOutput3, None},
Initialization :> (
{startTime, endTime} = {0, 1};
{irrelevantOutput1, irrelevantOutput2, tmax, irrelevantOutput3} =
simulationOutput;
)
]


Unfortunately when working with Manipulate and Dynamic (and to some extent with any functionality that has an unusual evaluation order) the scoping constructs available need fairly much care to achieve what one wants without unexpected side effects...

-
+1 Nice explanation of a difficult question! –  Michael E2 Jun 14 '13 at 14:30
Just to clarify, I suppose by values of local variables being small or large, you mean their (memory) size? –  Michael E2 Jun 14 '13 at 14:34
@MichaelE2: yes, sure. I meant the memory size. I'll edit the answer. Thanks for the clarification... –  Albert Retey Jun 15 '13 at 10:38
@AlbertRetey - thank you! So, to clarify, if I want the performance to be as fast as possible, then I would still have to fall back on the first section of code, yes? –  Vincent Tjeng Jun 17 '13 at 2:07
FYI, I think I've fixed all of the issues with the wonky timing of Deinitialization (for Dynamic, DynamicModule, and all derivative constructs such as Manipulate) for v10. –  John Fultz Apr 29 '14 at 2:31