Re: Re: DynamicModule question
- To: mathgroup at smc.vnet.net
- Subject: [mg88652] Re: [mg88611] Re: DynamicModule question
- From: John Fultz <jfultz at wolfram.com>
- Date: Sun, 11 May 2008 15:15:27 -0400 (EDT)
- Reply-to: jfultz at wolfram.com
On Fri, 9 May 2008 07:17:53 -0400 (EDT), Jean-Marc Gulliet wrote:
> J. McKenzie Alexander wrote:
>
>> Can someone please explain to me why the following happens? It's a
>> silly little example to illustrate a problem I ran into recently...
>>
>> First, evaluate the following in separate cells:
>>
>> Needs["PieCharts`"];
>>
>> data = {.25, .75}
>>
>> Then evaluate the following:
>>
>> DynamicModule[{size = 300},
>> Column[{
>> Slider[Dynamic[size], {100, 500}],
>> Dynamic[PieChart[data, ImageSize -> size]]
>> }]
>> ]
>>
>> Notice that you can not only resize the graphic by dragging the
>> slider, but if you change the definition of data, that's reflected
>> automatically in the graphic as well.
>>
>> However, suppose you wrap the DynamicModule in a function like so:
>>
>> foo[data_] := DynamicModule[{size = 300},
>> Column[{
>> Slider[Dynamic[size], {100, 500}],
>> Dynamic@PieChart[data, ImageSize -> size]
>> }]
>> ]
>>
>> Now evaluate
>>
>> foo[ data ]
>>
>> If you change the definition of data in the notebook, the second
>> DynamicModule doesn't update the pie charts. I don't understand what
>> breaks when you wrap the DynamicModule in a function definition.
>>
> Try
>
> Dynamic@foo[data]
>
> Now, why Dynamic is needed here? I do not know. Looking at the
> expressions in the output cells (Shift + Cmd + E ) for the code
> generated by entering directly the DynamicModule or by using a function
> both resulting expressions look very similar (even identical, as far as
> I can trust my sight :-)
>
> Regards,
> -- Jean-Marc
Jens knows the answer (his reply to this thread was quite correct), but he
expects the student to do all the work to figure out why his solution works. :)
I'll provide you some hints. It has to do with evaluation order.
When you evaluate foo[data], 'data' evaluates before 'foo' ever sees it. The
only thing 'foo' sees is {.25, .75}. Function scoping does a lexical
replacement of the data_ variable, so the resulting Dynamic is actually...
Dynamic at PieChart[{.25, .75}, ImageSize->size]
That's not very helpful. The first example worked because 'data' wasn't a
lexically scoped function variable, but a real variable which required
evaluation. And no evaluation happens inside of Dynamic until it reaches the
front end because Dynamic is HoldFirst.
In your final example, Dynamic@foo[data] works because now, the variable data is
evaluating inside the Dynamic.
So, in the simplest case...
a:=2;
Function[{x},Dynamic[x]][a] (*creates a Dynamic which evaluates '2', *not* 'a'*)
Function[{x},Dynamic[x],{HoldAll}][a] (*creates a Dynamic which evaluates 'a'*)
Sincerely,
John Fultz
jfultz at wolfram.com
User Interface Group
Wolfram Research, Inc.