MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Dynamic changing of variables

  • To: mathgroup at smc.vnet.net
  • Subject: [mg96365] Re: [mg96314] Dynamic changing of variables
  • From: John Fultz <jfultz at wolfram.com>
  • Date: Thu, 12 Feb 2009 06:37:57 -0500 (EST)
  • Reply-to: jfultz at wolfram.com

A note to anybody who makes non-trivial Dynamic interfaces.  Read the question and my response and understand it thoroughly.  This is a really important 
question and understanding the answer will help you to create very sophisticated and powerful Dynamic interfaces with no need for guesses or trial and error.

The error here is in the statement...

> In order to update "a" with the actual value of Sin[b] I need
> Dynamic around it. Unfortunately, now the variable "a" is invisibly

or, more specifically, what the definition of "it" is (take the oblique 
reference to a U.S. presidential quote as you will).  Yes, you do need to 
introduce a Dynamic to get a=Sin[b] to evaluate, but putting it on the 
right-hand side of the assignment is wrong in this context.  The key is to 
remember that Dynamic does not control anything about evaluation directly. What it does is to create a spot on the screen which has evaluation properties.

If, for example, you were to evaluate the following in a fresh Mathematica 
session...

b=5;
Dynamic[a=b];
b=6;
Print[a];

...then what will be printed?  Instead of evaluating it immediately, think about 
it before you try it.  Hint...it's a trick question, but understanding the trick 
will open your mind to exactly what Dynamic is doing.

The answer, which I will not reveal here (because you should really try it for 
yourself!) can be explained by the fact that the Dynamic never did anything
because it never showed up onscreen.  The semicolon inhibited the onscreen 
appearance of Dynamic, and without appearing onscreen, the evaluation of Dynamic 
accomplishes nothing.

More subtly, if you remove all of the semicolons, the Print[] statement (at
least on my machine) *still* remains unchanged, but now for a completely 
different reason.  That's because the onscreen placement of a Dynamic guarantees 
that its contents will be evaluated, but not *when* they'll be evaluated. My 
example sets up a race condition which, at least on my machine in v7, the 
Shift+Enter evaluation wins.


If I understand the intent of your example correctly, the place to begin is
here...

DynamicModule[{a, b = 0}, Dynamic[a = Sin[b];
  Column[{Dynamic[a], Slider[Dynamic[b], {0, 2*Pi}]}]]]

I.e., wrap the Dynamic around the entire CompoundExpression including the 
assignment and the Column.

You say this is a toy example that represents a real-world one.  I believe 
that...I've written things that look like your toy example many times.  It's a 
shame I'm not seeing your real example, though, because there are some further 
simplifications and improved efficiencies which I might be able to comment on.  
For example, in this case it's a bit wasteful that the Column[] is inside of a 
Dynamic[].  It could be a static element which contains individual Dynamic 
elements.  Something like...

DynamicModule[{a, b = 0},
 Column[{Dynamic[a = Sin[b]; a], Slider[Dynamic[b], {0, 2*Pi}]}]]

which is obviously silly in this example, but may point to something interesting 
in your real-world code.  Perhaps a generalization I could remark on is the
notion of an onscreen Dynamic which has no visual appearance.  Something like 
this...

DynamicModule[{a, b = 0}, Row[{Dynamic[a = Sin[b]; Spacer[0]],
   Column[{Dynamic[a], Slider[Dynamic[b], {0, 2*Pi}]}]}]]

This is a more sophisticated technique in which Row[] is used to show a Dynamic 
which takes essentially no onscreen space, and yet has an onscreen presence.  In 
this version, the Row[] and Column[] are static elements which are never 
regenerated by Dynamic.  And we can now more tightly confine the evaluation
behaviors of the elements of the Column so that they are regenerated on an 
as-needed basis, rather than every time any variable in the whole interface
changes.

I recommend re-reading the Advanced Dynamic Functionality tutorial (or reading 
it if you haven't already) in light of some of the things I've said here.  
Especially the subsections "Automatic Updates of Dynamic Objects" and "Nesting 
Dynamic".  You can find it by typing tutorial/AdvancedDynamicFunctionality in 
your help window.

Sincerely,
 
John Fultz
jfultz at wolfram.com
User Interface Group
Wolfram Research, Inc.




On Wed, 11 Feb 2009 05:22:24 -0500 (EST), Patrick Scheibe wrote:
> Hi,
>
> assume the following code lines:
>
> DynamicModule[{a, b  0},
> a = Dynamic[Sin[b]];
> Column[{
> Dynamic[a],
> Slider[Dynamic[b], {0, 2*Pi}]
> }]
> ]
>
> In order to update "a" with the actual value of Sin[b] I need
> Dynamic around it. Unfortunately, now the variable "a" is invisibly
> wrapped and completely useless for further calculations. I'm not able to
> calculate even a+1 inside the DynamicModule.
>
> DynamicModule[{a, b = 0},
> a = Dynamic[Sin[b]];
> Column[{
> Dynamic[a+1],
> Slider[Dynamic[b], {0, 2*Pi}]
> }]
> ]
>
> If I'm not just too stupid and this behaviour is intended, then I'm
> wondering whether this doesn't lead to problems when you have more
> complex constructs with several dynamic variables.
>
> Cheers
> Patrick
>
> PS: I was just pointed by another person on this and I found a way
> around it. So cannot provide a real problem I'm having. Nevertheless, I
> would be glad to know what you think since I couldn't really find the
> point in the documentation where this is explained.





  • Prev by Date: Re: LabeledListPlot
  • Next by Date: Re: Re: Re: testing if a point is
  • Previous by thread: Re: Dynamic changing of variables
  • Next by thread: Re: Re: Dynamic changing of variables