MathGroup Archive 2011

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

Search the Archive

Re: What is the point of having Initializations in DynamicModule and Manipulate?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg123095] Re: What is the point of having Initializations in DynamicModule and Manipulate?
  • From: John Fultz <jfultz at wolfram.com>
  • Date: Wed, 23 Nov 2011 07:06:16 -0500 (EST)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • Reply-to: jfultz at wolfram.com

On Tue, 22 Nov 2011 20:52:15 +0100, Fred Simons wrote:
> With much interest I follow this discussion. In particular I want to
> thank John Fultz for his clear explanation on why DynamicModule behaves
> as it does.
>
> For me, a little question still open: what exactly happens when the
> intialization option is evaluated?

The rhs of the Initialization option, as it was formulated by MakeBoxes and
delivered to the front end, is sent by the front end to the kernel. Normally, I 
wouldn't bother making this distinction...I would just tell people to always use 
RuleDelayed because using Rule is never what you want...but I'll entertain your 
question as an academic discussion about how evaluation works without advocating 
people actually copy anything you do here in code they actually want to use.

> In the examples so far it is used as
> a delayed rule, so the rule will be applied first and then evaluation
> takes place. But evaluation of what?

The important thing to remember is that there are two sorts of things happening, 
and you should never conflate the two.  The kernel *evaluates* its result, then 
*typesets* it for the front end.  If you want to deeply understand how Dynamic 
and DynamicModule works, you need to understand this distinction, as well as the 
various other things I've laid out.

So, an initial question you should be asking yourself which would help to 
understand some of the issues you raise is, what happened in evaluation...i.e., 
what expression was actually passed to MakeBoxes for typesetting?

This is really easy to figure out, actually.  Just wrap InputForm around the
input, and you'll see exactly what evaluation did.  For example, I think using 
InputForm is pretty instructive in an example like this:

In[1]:= 
DynamicModule[{a=7,b,c},b=5;Dynamic[a,b],Initialization:>(c=3)]//InputForm
Out[1]//InputForm=
DynamicModule[{a = 7, b = 5, c}, Dynamic[a, 5], Initialization :> (c = 3), 
 DynamicModuleValues :> {}]

InputForm shows you that the b=5 evaluated and changed the DynamicModule 
initialization...but the c=3 did not.  Okay...preface finished...now onto your 
specific questions.


> Anyway the side effect is that, in
> the last example of Mike, a value is assigned to g, but too late to be
> displayed in the dynamic module, and even in the output for g itself
> when it was asked for in the same cell:
>
> In[1]:= Clear[g]; DynamicModule[{},g,Initialization:>{g="hello world"}]
> g
> Out[1]= g
> Out[2]= g
>
> However, when we give these two commands in two input cells, the second
> output now shows the value of g instead of the name g:
>
> In[3]:= Clear[g]; DynamicModule[{},g,Initialization:>{g="hello world"}]
> Out[3]= g
>
> In[4]:= g
> Out[4]= hello world
>
> This is something I think I understand. But the following is less clear
> to me. For the initialization we will use now the immediate rule. Then
> the result is what Mike is expecting:
>
> In[5]:= Clear[g]; DynamicModule[{},g,Initialization->{g="hello world"}]
> Out[5]= hello world

So, the question is, how did DynamicModule evaluate?  This is easy to figure
out.  Although DynamicModule is HoldAll, virtually all functions in Mathematica 
evaluate their options regardless of the HoldAll status (in this case, 
DynamicModule is HoldAll because of the need to hold its first two arguments).  
I'm not aware of any exceptions to that rule (maybe somebody else knows 
something I don't).

And Rule immediately evaluates its rhs...that is the one thing which 
distinguishes it from RuleDelayed.

So, we might surmise that, during evaluation, the following bit:
   Initialization->{g="hello world"}

might evaluate to Initialization->{"hello world"} with the side effect of having 
set g.  And, in fact, InputForm confirms that:

In[5]:= Clear[g]; 
DynamicModule[{}, g, Initialization -> {g = "hello world"}] // InputForm

Out[5]//InputForm=
DynamicModule[{}, "hello world", Initialization :> {"hello world"}, 
 DynamicModuleValues :> {}]

When this DynamicModule typesets, it doesn't hold {g="hello world"} in its 
Initialization...merely {"hello world"}.  And you've now created a DynamicModule 
with an Initialization which is not going to work in future kernel sessions, so 
it's not very useful.  This is exactly why I would say that it's best merely to 
always avoid Rule in the Initialization option.


> When the frontend asks for evaluation of the intialization only when it
> is displaying the dynamic module, it is still too late for using the
> value for g, just as with the delayed rule, and we would have seen the
> name g in the output. So my feeling is that the right hand side of the
> immediate initalization is evaluated already during the shift-enter
> evaluation. The following modification seems to confirm this, and raises
> more questions:
>
> In[6]:= Clear[g];
> DynamicModule[{},Print[13];g,Initialization->{Print[12];g="hello world"}]
> During evaluation of In[6]:= 12
> During evaluation of In[6]:= 12
> During evaluation of In[6]:= 12
> During evaluation of In[6]:= 12
> During evaluation of In[6]:= 13
> Out[6]= hello world
>
> The number 12 is printed even four times (see the recent question of
> David Park on how often initialization is done) and only after that we
> see the effect of the print statement in the argument of the dynamic
> module, resulting in the display of the value of g.

As I mentioned earlier, DynamicModule is HoldAll.  Which means that even its
options are held initially, but evaluated and processed in the internal 
implementation of DynamicModule.  What you're seeing here isn't specific to the 
Initialization option...it happens with every option (even invalid ones), too.

In an ideal world, that processing would only trigger a single evaluation of its 
options.  My guess is that allowing the options to be evaluated multiple times 
allowed the implementation of DynamicModule to be much simpler.  I think I would 
stipulate this as a minor bug, but probably so minor that it would never affect 
any real-world code.


> Any comment is highly appreciated.
>
> Fred Simons
> Eindhoven University of Technology

Sincerely,

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



  • Prev by Date: Re: How to do quickest
  • Next by Date: Re: How to do quickest
  • Previous by thread: Re: What is the point of having Initializations in DynamicModule and Manipulate?
  • Next by thread: Re: What is the point of having Initializations in DynamicModule and Manipulate?