Re: What is the point of having Initializations in DynamicModule and Manipulate?
- To: mathgroup at smc.vnet.net
- Subject: [mg123031] Re: What is the point of having Initializations in DynamicModule and Manipulate?
- From: John Fultz <jfultz at wolfram.com>
- Date: Mon, 21 Nov 2011 04:26:55 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- Reply-to: jfultz at wolfram.com
This is no accident. It's very carefully thought out design. Question...what do I do if I want thing A to evaluate before thing B? Why, of course, use any number of Mathematica paradigms for sequential evaluation. The semicolon, representing CompoundExpression, for example. No need to invent anything here. Further question...what if I want thing A to evaluate before thing B, but thing B is part of a dynamic interface. This is the interesting question. There are absolutely no guarantees about the order in which two discrete Dynamics will evaluate, so I can't set up multiple Dynamics in a row to evaluate in sequence. I could nest Dynamics (outer ones always evaluate before inner ones), but then I may have to play some tricky games with Refresh to prevent code from evaluating which should only ever evaluate once. So, what I want is an Initialization option. Guaranteed to only ever evaluate once, and always evaluates before its Dynamic contents. So, we added the Initialization option to Dynamic. But we later realized that a similar problem comes up with DynamicModule. It's quite reasonable to want to "prime" a DynamicModule when the FE instantiates/displays it, which might involve setting initial values of the DynamicModule variables, but it might also involve a bunch of other related code evaluation (common example, loading a package). So, we added the same concept of an Initialization option of DynamicModule as to Dynamic. And it works in exactly the same way...it does not evaluate until the FE is ready to display the DynamicModule, and then it queues to the Initialization option to happen first, and once only. So, what about the issue of code inside a DynamicModule which is not wrapped in Dynamic? Well, it's very important to understand that this code will never, never, ever evaluate again after the Shift+Enter evaluation. It does not evaluate when you load the notebook in a new session, for example. So, any code inside of a DynamicModule, but not wrapped inside of a Dynamic, is UTTERLY USELESS, except insofar as it has side effects on setting DynamicModule variables which might be remembered in future sessions. Any code which does anything else is going to not be remembered in future sessions, and therefore risks creating interfaces which are busted in ways which aren't obvious unless you're testing for this sort of thing. Furthermore, it introduces a weird evaluation order problem because you're mixing code evaluated at Shift+Enter time with code evaluated when the DynamicModule is actually displayed onscreen. It's more bizarre than Dynamic...as I've mentioned before, the result of evaluating: Dynamic[a=5]; does *not* set a because the contents of the Dynamic never evaluate because the contents were never displayed onscreen. DynamicModule inherently wants to be, by design, a Dynamic-like construct...i.e., it does what it does when displayed onscreen, and in tandem with dependent Dynamics or DynamicModules. But unlike Dynamic, DynamicModule does actually evaluate its contents at Shift+Enter time, to allow for the convenience of introducing non-trivial code for setting the variables. Now, let's suppose that you wanted the Initialization option to evaluate before that code. What you would get is something even more bizarre and confusing. You would have to do one of two things... Option 1: Evaluate the Initialization option during Shift+Enter evaluation *and* when the FE instantiates/displays the DynamicModule. Which means that you get a double-evaluation affecting the same DynamicModule variables. I hope I don't have to say why double-evaluations are bad in the general case. Option 2: The Initialization option would have to work differently for DynamicModules depending upon how and when the results were created. I.e., it would fire during Shift+Enter evaluations sometimes, and during FE instantiation/display sometimes. Which would also make the results much more difficult to understand, and I'm frankly not even sure how I would handle some of the corner cases to read the user's intent (what should a DynamicModule in an ExpressionCell do, for example?). DynamicModule lives firmly in the world of FE-instantiated evaluation, despite the ability to initialize its variables at Shift+Enter time. The correct design is for all of its options to similarly live in the world of FE-instantiated evaluation. Sincerely, John Fultz jfultz at wolfram.com User Interface Group Wolfram Research, Inc. On Sat, 19 Nov 2011 06:46:53 -0500 (EST), Armand Tamzarian wrote: > I'd be interested in feedback from other users about the way in which > Initializations works within DynamicModule (and Manipulate?). It is > fair to say that I expected an initialization to occur "initially." > That is to say I expected Initialization content to be evaluated prior > to the body of the DynamicModule. I have exchanged emails with tech > support about this. Attached is an example sent to me by tech support. > > ClearAll[plot, g]; > > (* and in a separate cell *) > DynamicModule[{c}, {plot, Slider[Dynamic[c]], g[Dynamic@c]}, > Initialization :> (g[x_] : Cos[x]; plot = Plot[g[x], {x, 1, 10}]), > UntrackedVariables -> {g}] > > It is important for this example to keep the ClearAll line in a > separate cell so that the global variables are only cleared once. On > my system (OS X 10.6.8, Mathematica 8.0.4) the output is a list > > {plot, "slider", g[0.]} > > where "slider" is the actual rendered slider but plot is the word > (unset variable) plot. In other words Global`plot has no value at the > time the body of the DynamicModule is evaluated. Ditto Global`g. > > If you evaluated the cell (the second cell with the DynamicModule) a > second time a plot graphic appears in the list and g[0.] becomes > Cos[0.]. This is not surprising because Global`plot and Global`g now > have a value. > > Wolfram have indicated that this is working as designed -- which is > presumably why this example was sent to me of how this should work. If > that is the case it seems poorly designed because (and it is here I > would like feedback) users would expect initializations to be > evaluated prior to the body of the DynamicModule -- otherwise what is > the point? > > I'd appreciate the thoughts of other users about this. > > Additionally I have been told by Wolfram that wrapping Dynamic around > the variable(s) that are not being evaluated will trigger the > evaluation. But why would a user want to make plot or g Dynamic? It > seems to me that the entire purpose of having an Initialization is to > evaluate this "one off" variable/functions. > > thanks > > Mike