18
$\begingroup$

I'm putting my new copy of Mathematica 10 through its paces and I noticed a weird change in the colouring scheme that I find very annoying, and I'd like to get some insight into why it's happening.

The change happens, as far as I can tell, for variables that have been set in some scoping construct which are then used inside of a Manipulate command. Thus, for example, the code

Module[
 {A = 1},
 Manipulate[
  Plot[
   A Sin[k x]
   , {x, 0, 20}
   ]
  , {k, 1, 10}
  ]
 ]

renders differently in the Mathematica 9 and 10 frontends:

enter image description here

Playing around in Edit > Preferences > Appearance > Syntax Coloring > Errors and Warnings, the error class that this is attributed to is

Variables that will go out of scope before being used

though what that means exactly isn't very clear to me. Therefore, I have some questions:

  • Is this in fact an incorrect usage? If so, why, and what alternative construct should I use? (I notice, in particular, that in version 10 the red colour is displayed for Block and Module but not for With.)

  • Why did this only start happening in version 10? Which version is right?

  • If this sort of code is OK, can I safely disable this sort of error marking? What risks does that entail?

$\endgroup$
12
  • $\begingroup$ You can nest Module within Manipulate (and I think nesting it the other way around is what caused the syntax warning because the Manipulate did not play nice with the Module outside of it). Or as you said you can use With, and in this case it's acceptable to do so as A is basically just a constant that does not change its value when the code is run. $\endgroup$ Commented Jul 17, 2014 at 12:04
  • $\begingroup$ Is there some specific reason why the inverted order (i.e. Module inside the Manipulate) is preferable? $\endgroup$ Commented Jul 17, 2014 at 12:05
  • $\begingroup$ I have no clue, but I'd like to add that if you nest Module within Manipulate, your Module variables can depend on the manipulate parameter, whereas you cannot achieve this the other way around (as the manipulate parameter disappears outside of the scope of the Manipulate block). You can try this to see what I'm talking about: 'Manipulate[Module[{A = k}, Plot[A Sin[3 k x], {x, 0, 20}]], {k, 1, 10}]. Of course in your case that's not going to be important since your Module variable does not change, hence the use of With` will be just fine. $\endgroup$ Commented Jul 17, 2014 at 12:17
  • $\begingroup$ This is an issue for me as certain applications I'm using do need this. Note, however, that code of the form Module[{A}, Manipulate[A = k; Plot[A Sin[k x], {x, 0, 20}], {k, 1, 10}]] works fine in both v9 and v10, but only v10 colours it as incorrect syntax. $\endgroup$ Commented Jul 17, 2014 at 12:29
  • 1
    $\begingroup$ See the section "Module"/"Advanced usage" in this answer for an example of a closure. Anyway, after reading the documentation of DynamicModule I think I now figured out what the problem with Module+Manipulate probably is: Dynamic content (like Manipulate) is stored across sessions. However a normal Module variable is not stored that way. I guess that would create problems as soon as you save the notebook and later open it in a new instance of Mathematica. $\endgroup$
    – celtschk
    Commented Jul 18, 2014 at 11:10

2 Answers 2

21
$\begingroup$

Based on Mr.Wizard's answer and comments by Szabolcs and celtschk, I now understand that the code I posted does have undesirable side-effects and it should be avoided. Specifically, the scoping constructs Module and Block are meant to completely localize the variables in their first argument (for more information see this question). However, placing their scoped variables inside a Manipulate (or other dynamic construct) can cause the values to leak, and this should be avoided - hence the syntax error marks.

TL;DR:

Behaviour of the form

Block[{v}, Dynamic[v = 1]]
v

(*
1
1
*)

is unwanted. Scoping constructs which contain Dynamic objects like Manipulate should be replaced by With or DynamicModule.

Modules localize their variables by creating new local variables that are unique for the session. Thus, inside Module[{A}, ... ], the variable A gets replaced by a variable of the form A$1234, and this should not be accessible outside of the Module:

Module[{A},
 Print[A]; A = 1
 ]
(*
A$464
1
*)

A$464
(*
A$464
*)

Placing a Manipulate inside the Module, though, can cause this value to leak:

Module[{A},
 Print[A];
 Manipulate[A = k, {k, 1, 2}]
 ]

will produce e.g. A$524 and the Manipulate, and then asking for that variable gives

A$524
(*
1
*)

Block is similar but slightly worse, as it is now the value of the scoped variable itself that can leak. The expected behaviour is

Block[
 {A},
 Print[A];
 A = 1
 ]
A
(*
A
1
A
*)

but with a Manipulate inside, the value of A outside the Block can change:

Block[{A},
 Print[A];
 Manipulate[A = k, {k, 1, 2}]
 ]

returns A and the Manipulate, and then asking for A returns

A
(*
1
*)

This is indeed incorrect and should be avoided.

The correct way to go about it, then, appears to be using a DynamicModule whenever there are dynamic objects inside the scoping construct. This type of Module is indeed capable of containing the side effects described above. Thus,

DynamicModule[{A},
 Print[A];
 Manipulate[A = k, {k, 1, 2}]
 ]

will produce e.g. A$827 and the Manipulate, and now the scoped variable A$827 is properly contained:

A$827
(*
A$827
*)

For further details about this, and about the differences between Module and DynamicModule, see Advanced Dynamic Functionality - Module versus DynamicModule. For more on the behaviour of Module, Block and With in different circumstances, see this question.

$\endgroup$
2
  • $\begingroup$ Well done! Thanks for the great lesson. $\endgroup$ Commented Jul 17, 2014 at 19:19
  • 1
    $\begingroup$ Nice self answer. +1 $\endgroup$
    – Mr.Wizard
    Commented Jul 18, 2014 at 4:48
8
$\begingroup$

I believe that highlighting is there specifically to encourage you to use DynamicModule rather than Module:

DynamicModule[{A = 1}, Manipulate[Plot[A Sin[k x], {x, 0, 20}], {k, 1, 10}]]

One reference:

Also related:

$\endgroup$
3
  • $\begingroup$ So the rule of thumb is to use DynamicModules whenever there are Dynamic-like constructs like Manipulate inside? $\endgroup$ Commented Jul 17, 2014 at 14:14
  • 2
    $\begingroup$ Manipulate is evaluated in a special way, that I don't understand fully. It is not actually evaluated, just formatted in a special way. After creating a Manipulate, checking its InputForm shows that the head is still Manipulate. Anyway, the point is that by the time the guts of Manipulate get evaluated, that variable A is not localized any more. ... $\endgroup$
    – Szabolcs
    Commented Jul 17, 2014 at 14:14
  • 4
    $\begingroup$ ... For some reason, the Manipulate still seems to work as one would naively expect, but that's only because A$1234 has leaked from Module and is not being cleared as it normally would. To sum up: it looks like a very bad idea to use Module around Manipulate. $\endgroup$
    – Szabolcs
    Commented Jul 17, 2014 at 14:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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