# Issues with Dynamic's second-argument functions

First:

According to the documentation Dynamic[expr,f] evaluates f[val,expr] during interactive changing or editing. Now check this example:

DynamicModule[{y, g},
Column[{
Manipulator[Dynamic[y, (y = #; g = {#1, ##2}) &]],
{"y", {"val", "expr"}},
Dynamic[{y, g}]
}]]


When you move the slider you will find there is a lag between g[[1]] (val) and g[[2]] (expr) .

Note:

I am not looking for solution of this (because one can do Dynamic[expr,{f,fend}]). Just I want to understand how does this behavior happen

Second:

When we have three functions, Dynamic[expr,{fstart,f,fend}] typically evaluates fstart[val,expr] once when the mouse is pressed, then evaluates f[val,expr] whenever the mouse is moved, and then evaluates fend[val,expr] once when the mouse is released. Now check this example:

col = None; {Slider[
Dynamic[x, {(col = Blue; x = #) &, (col = Red;
x = #) &, (col = Green) &}], Background -> Dynamic[col]],
Dynamic[x]}


It is clear (as I can see) when mouse is pressed, Blue color Background does not show up which means the fstart[val,expr] is not evaluated.

Any explanation for this?

-

The argument ##2 is simply evaluated to the current setting before it is passed to the function, and #1 is the new setting. For instance, if the new val is 0.2 and expr is y, whose current value is 0.1, then f[val, expr] first becomes f[0.2, 0.1], which then evaluates accordingly.

Compare with a function that holds its arguments, so that y will be evaluated after setting y to the new value:

DynamicModule[{y, g},
Column[{Manipulator[
Dynamic[y, Function[{v, e}, (y = v; g = {v, e}), HoldAll]]],
{"y", {"val", "expr"}}, Dynamic[{y, g}]}]]


-
+1, The second explanation (function with HoldAll) is really interesting. could you let me know in the OP case, what decides about the lag value. – Algohi Mar 5 at 19:25
@Algohi The lag is the current vs. new settings (before the function evaluates): the 0.1 vs 0.2 in my answer. g is set equal to the expression {0.2, 0.1}; it is not set equal to the expression {0.2, y}. That is ##2 is 0.1 and not y. Does that help? Or do you mean a different kind of lag? – Michael E2 Mar 5 at 20:14
What I meant is that in the OP when you move the slider you will notice that the difference between val and expr (Differences@g) is either 0.006 or 0.004. I just want to know why specifically what chooses these values. Of course if the Manipulator range is different then the lag is different. – Algohi Mar 5 at 20:40
That is what I explained. Before you click the mouse, y has a value in the slider. Call it the "current value" 0.1. You move the slider to position 0.2; call it the "new value". Before the dynamic updating function is called then, y has the value 0.1 and it will eventually be set to 0.2 in the function. Let's abbreviate your function (y = #; g = {#1, ##2}) & by f. Next the function is called: f[0.2, y]. Mathematica first evaluates the arguments to get f[0.2, 0.1], since f is not HoldAll. Finally f sets y to 0.2 and g to {0.2, 0.1}. Does that help? – Michael E2 Mar 5 at 20:48
@Algohi A computer takes discrete steps at discrete intervals. Not only temporally does it read devices, such as a mouse, at discrete times, but spatially a mouse position is discretized, at a coarser level than floating-pt numbers, probably at pixel resolution, certainly by the computer system, and probably not discretized further by Mathematica. You can diminish the spatial effect by holding down the option and shift keys. Aside from the effect of the keys, Mathematica probably does little else relative to the "lag" except rescale the image size to the numeric scale of the slider. HTH. – Michael E2 Mar 5 at 21:51

It appears that f beings immediately after fstart ends leaving no time for you to see the effect.

Consider

col = None;
{Slider[
Dynamic[x,
{(col = Blue; Print["Start"]; x = #) &,
(col = Red; Print["Interactive"]; x = #) &,
(col = Green) &}
], Background -> Dynamic[col]],
Dynamic[x]}


When you press and hold the slider without moving it you immediately get the red background and output:

> Start
> Interactive


This shows that fstart is being called.

You can make use of FinishDynamic and Pause to get the affect you are looking for.

col = None;
{Slider[
Dynamic[x,
{(col = Blue; FinishDynamic[]; Pause[0.1]; x = #) &,
(col = Red; x = #) &,
(col = Green) &}
], Background -> Dynamic[col]],
Dynamic[x]}


Now the background turns blue for a tenth of a second before turning red and manipulating the slider.

Hope this helps.

-