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.
- Follow-Ups:
- Re: Re: Dynamic changing of variables
- From: Patrick Scheibe <pscheibe@trm.uni-leipzig.de>
- Re: Re: Dynamic changing of variables