6
$\begingroup$

I'm confused about the best approach to localizing symbols used in a Manipulate. I understand that Manipulate does a good job by default of localizing symbols defined in its list of controls (even if these are custom controls). But it appears that symbols defined in the first argument, or those initialized with an Initialization option, are not localized. For example, in the following, z, r, and q (and naturally x) are local, but y and t are not:

Manipulate[
    y = 4*x;
    Plot[y*x^z+t[q], {x, 0, r}],
    {z, 0, 5},
    Row[{Control@{{r,2}, 2, Dynamic@q}}],
    {{q,10}, 5, 20},
    Initialization:> (t[i_]:=5*i)
]

Wrapping the whole Manipulate in a Model[{y,t}, ... seems to work, but marks y and t in the Manipulate in red (on macOS) which leaves me wondering if it's the right thing to do.

There are two approaches that seem to work partially, but not altogether:

DynamicModule

Wrapping in DynamicModule works to localize any symbols not localized by Manipulate

DynamicModule[{y,t},
    Manipulate[
        y = 4*x;
        Plot[y*x^z+t[q], {x, 0, r}],
        {z, 0,5},
        Row[{Control@{{r,2}, 2, Dynamic@q}}],
        {{q,10}, 5, 20},
        Initialization:> (t[i_]:=5*i)
]]

but this places y and t in an outer scope, which seems the wrong way to proceed.

ControlType -> None

For some symbols, the form {sym, None} works to localize sym, but only it seems for limited cases. For example

Manipulate[
    y = 4*x;
    Plot[y*x^z+t[q], {x, 0, r}],
    {z, 0, 5},
    Row[{Control@{{r,2},2,Dynamic@q}}],
    {{q,10}, 5,20},
    {y, None},
    Initialization:> (t[i_]:=5*i)
]

localizes y. But similar attempts to localize a function such as t fail.


What is the correct approach to localizing symbols inside Manipulate? Is there are reason to prefer DynamicModule over ControlType -> None in general, or vice versa? How should local functions be localized (esp. if the natural thing to be ding is specifying them in Initialization)?



Additionally, controls defined with Control@ don't highlight the associated symbols to indicate localization, which makes it very hard to read through code and understand how things are scoped. DynamicModule can be used to fix this (and even leaves the symbol in the inner Manipulate scope).

$\endgroup$
  • 1
    $\begingroup$ Manipulate only localizes control variables. If you want more localization see DynamicModule. Since Manipulate is a front-end thing (it's a cousin of Dynamic) you'll want the front-end version of Module--i.e. DynamicModule. In fact Manipluate resolves to a DynamicModule when viewed. $\endgroup$ – b3m2a1 Sep 5 '17 at 15:42
  • $\begingroup$ To localize, for example r, you can add {{r, 2}, None} after {{q, 10}, 5, t}. $\endgroup$ – Karsten 7. Sep 5 '17 at 15:45
  • $\begingroup$ Let us continue this discussion in chat. $\endgroup$ – b3m2a1 Sep 5 '17 at 16:11
  • 1
    $\begingroup$ Closely related: 17112, 72422 $\endgroup$ – Kuba Sep 5 '17 at 16:41
  • 1
    $\begingroup$ Also related: 13658, It is possible that much of what is discussed in the comments has been fixed in the intervening (nearly) five years. $\endgroup$ – m_goldberg Sep 5 '17 at 17:10
4
$\begingroup$

Because of the interactions of the various sliders, I would wrap the Manipulate expression in a DynamicModule expression that defines and localizes y and t. I would also define y as a function. Like so:

DynamicModule[{y, t},
  Manipulate[
    Plot[y[x]*x^z + t[q], {x, 0, r}],
    {z, 0, 5, Appearance -> "Labeled"},
    Row[{Control @ {{r, 2}, 2, q, Appearance -> "Labeled"}}],
    {{q, 5}, 5, t[i], Appearance -> "Labeled"},
    {{i, 3}, 1, 5, 1, Appearance -> "Labeled"}],
  Initialization :> (y[x_] := 4*x; t[i_] := 5*i)]

demo

I had to introduce the i slider because, without something like it, the OP's code as given in the question is not functional.

Update

My experience is that the form {{var, intitVal}, None} works well when var is used to introduce a simple variable, such as temporary used to help break up a complicated computation. To localize more complex things, such as function definitions, I prefer to take the route I show in this answer.

$\endgroup$
  • $\begingroup$ Fixed the bug in the code. Also focused on the several issues raised. $\endgroup$ – orome Sep 5 '17 at 18:10
  • $\begingroup$ And r? What's the reason for the different coloring; is it meant to mean something? DynamicModule fixes it (and even keeps it in the the right scope). $\endgroup$ – orome Sep 5 '17 at 19:48
  • $\begingroup$ So this method appears superior in terms of brevity and clarity. Is there any real drawback to pulling things — here y and t — out into a new nesting scope? $\endgroup$ – orome Sep 5 '17 at 20:14
  • $\begingroup$ @raxacoricofallapatorius. Not that I know of. $\endgroup$ – m_goldberg Sep 6 '17 at 0:10
3
$\begingroup$

The {var, None} spec does work for functions if you use Clear. It just initially assigns 0 to them. So you can do this:

Manipulate[
 Plot[y[x]*x^z + t[q], {x, 0, r}], {z, 0, 5, Appearance -> "Labeled"},
  Row[{Control@{{r, 2}, 2, q, Appearance -> "Labeled"}}], {{q, 5}, 5, 
  t[i], Appearance -> "Labeled"}, {{i, 3}, 1, 5, 1, 
  Appearance -> "Labeled"},
 {y, None},
 {t, None},
 Initialization :> (
   Clear[y, t];
   y[x_] := 4*x; t[i_] := 5*i)
 ]
$\endgroup$
  • $\begingroup$ And r? What's the reason for the different coloring? (It seem the only way to avoid it is with DynamicModule; or initializing it a second time in a ControlType -> None control.) $\endgroup$ – orome Sep 5 '17 at 19:47
  • $\begingroup$ What's wrong with r? It's colored differently because it doesn't match SyntaxInformation[Manipulate]. $\endgroup$ – b3m2a1 Sep 5 '17 at 19:48
  • $\begingroup$ That's a bit circular though. The question is: if the coloring is meant to convey something, what is it meant to convey? Locals are clearly indicated, as are undefined symbols. The coloring for r corresponds to the latter. $\endgroup$ – orome Sep 5 '17 at 19:51
  • $\begingroup$ The coloring isn't handled by the kernel at all. It's handled by the front-end. The front end does static analysis to try to figure out what is what, but the front end is sometimes wrong. The coloring should be seen as a guideline. Usually the FE is right, but sometimes it misses things. $\endgroup$ – b3m2a1 Sep 5 '17 at 19:52
  • $\begingroup$ Ah, ok, that makes more sense: it's wrong. $\endgroup$ – orome Sep 5 '17 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.