MathGroup Archive 2011

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

Search the Archive

Re: Combining Slider and SetterBar in Manipulate

  • To: mathgroup at smc.vnet.net
  • Subject: [mg115255] Re: Combining Slider and SetterBar in Manipulate
  • From: John Fultz <jfultz at wolfram.com>
  • Date: Wed, 5 Jan 2011 05:47:35 -0500 (EST)

On Tue, 4 Jan 2011 18:53:35 -0500 (EST), AES wrote:
> In article <ifup6c$cnr$1 at smc.vnet.net>,
> JohnH <ununquadium113 at yahoo.com> wrote:
>
>>> Also...a bit of unsolicited advice.  Your use of Block is a *bad* idea.
>>> It's always bad to reference Block-scoped or Module-scoped variables
>>> declared outside of a Manipulate or Dynamic from within that
>>> Manipulate/Dynamic.  If you're wanting to localize the variable
>>> 'someData', then Manipulate offers you an easy way to do that.  Add
>>> someData as a control variable, but no control appearance.
>>>
> John, I haven't followed the earlier part of this thread (and scoping is
> something I try to think about as little as possible!), but could you
> expand on this a little?
>
> As an old Fortran programmer, I think in terms of subroutines.  So, in
> building a Manipulate I want to first define a "subroutine" (that is, a
> Module) which depends on, say, 2 or 3 explicit arguments, plus maybe a
> few global parameters which will have already defined values.  This
> subroutine will then return a numerical value or maybe a graphics object.
>
> Then I want to build a Manipulate in which some or all of the explicit
> arguments are controlled by Controls (others may be explicitly set
> within the Manipulate); call this subroutine (or maybe several such
> subroutines) within the Manipulate; and  Plot or Show the object
> returned by the subroutine, or something that depends closely on it,
> still within the Manipulate.
>
> I guess the primary objective of this approach is brevity of code within
> the Manipulate, plus just general modularity. Is the above a bad
> approach?  -- especially assuming that the overall notebook containing
> the Manipulate will be relatively brief and self-contained, and one
> needn't worry about side effects after the Manipulate has been used.

Sorry, there's no way to avoid discussing some detail of scoping to answer your
question, but I'll try to make it as painless as possible.

As you probably know, Manipulate is built on top of Dynamic.  I know you're
probably much more interested in Manipulate, but it's easier to explain if I
reference Dynamic directly.  But, in most places in my explanation, you can
replace "Dynamic" with "Manipulate" and get the basic idea.

The important thing to understand about Dynamic is that when you evaluate a
Dynamic, it does *not* immediately evaluate its contents.  This is why, for
example, that...

Dynamic[x==5];0

...does not, in fact, assign x the value 5.  A Dynamic, and therefore a
Manipulate, only gets evaluated when it gets displayed onscreen.

This is a real problem when you surround Dynamic or Manipulate with Block or
Module.  These scoping constructs have long since evaporated away by the time
the Dynamic gets evaluated, and so any scoping they did for the contents of
Dynamic is pretty much useless.  E.g.,

In[1]:== Block[{x==5},Dynamic[x]]
Out[1]== x

Incidentally, in this case, a bit of syntax coloring warns you that something
bad may happen.  Module is worse because it's a kind of scoping construct where
the scoping implementation can leak out.  So, you might know that, for example:

In[2]:== Module[{x},x]
Out[2]== x$139074

But what's trickier is what happens with Dynamic.  Because at first it looks
like it works:

In[3]:== Module[{x==5},Dynamic[x]]
Out[3]== 5

but this is just another form of Module leakage.

In[4]:== %//InputForm
Out[4]//InputForm== Dynamic[x$139080]

Recall that Dynamic did not evaluate its argument right away, so in fact, it
just carried the substituted 'x' straight out of the Module.

There are two scoping constructs which work well with Dynamic -- DynamicModule
and With.  DynamicModule[] works because, like Dynamic, it lives inside the
front end.  So, it localizes variables exactly when the Dynamic evaluates. 
With[] works because it's essentially a form of find-and-replace for expression
trees, rather than an attempt to localize variables.

Also, substitution of named function variables works well.  Function variable
substitution is a lot like With[].  This should slot very naturally into your
Fortran experience.  And you can generally use DynamicModule[] wherever you
would have used Module[] before.  But Block[]...well, that's just not a concept
which is compatible with how Dynamic works.

Understand that this only affects scoping constructs used outside of Dynamic (or
Manipulate).  Using them inside is just fine.

Sincerely,

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


  • Prev by Date: Re: Reduce in Mathematica 5 vs Mathematica 8 (2nd problem)
  • Next by Date: Text Color in Copied Text
  • Previous by thread: Re: Combining Slider and SetterBar in Manipulate
  • Next by thread: Re: Combining Slider and SetterBar in Manipulate