12
$\begingroup$

Shortly, definitions in form of e.g. x:= RandomReal[] have to be avoided inside DynamicModule[{x}, ...]. Why?, this Prints immediately:

DynamicModule[{x}, x := Print[1]; {}]

It hit us hard in the past, e.g.:

So what is the official rule here?

ref / DynamicModule / Details and Options / (-4)th bullet point

Ordinary values of symbols are saved in the first argument of the DynamicModule; other values are saved in the setting for the DynamicModuleValues option.

This is almost useless since "Ordinary values of symbols" and "other values" have no real meaning in Mathematica.

J. Fultz in ShearingTransform and Dynamic:

An issue which is causing confusion among the commenters is that DynamicModule, sadly, does not support SetDelayed on its member variables. SetDelayed is silently translated to Set.

Closer but not quite there yet, x[]:=RandomReal[] will work well.


$\endgroup$
  • 2
    $\begingroup$ really intriguing and helpful! $\endgroup$ – Wjx Jul 27 '16 at 8:43
14
$\begingroup$

J. Fultz' answer indicates that it is not a but a which needs better documentation.

Get a habit of defining your procedures with [], e.g. f[]:=Print[1]. (Which creates DownValues instead of OwnValues).

DynamicModule saves its variables' OwnValues in the first argument of that DynamicModule. Which does not support SetDelayed and is sliently translated to Set. (e.g. DynamicModule[{x := RandomReal[]}, {}] is left unevaluated)

Values other than OwnValues will be saved in DynamicModuleValues option and work as expected.

"Proof"

InputForm @ DynamicModule[{x}, x[] := RandomReal[]; {}]
DynamicModule[{x}, 
    {}, 
    DynamicModuleValues :> {{DownValues[x] = {HoldPattern[x[]] :> RandomReal[]}}}
]
 InputForm @ DynamicModule[{x}, x := RandomReal[]; {}]
DynamicModule[{x = 0.20406205529616095}, 
    {}, 
    DynamicModuleValues :> {}
]

I've already sent a report with a request to improve DynamicModule's documentation:

A support case with the identification [CASE:3676288] was created.

[...] I have filed a suggestion with the appropriate development team requesting that we better document how DynamicModule handles SetDelayed OwnValues. [...]

$\endgroup$
  • 2
    $\begingroup$ As I was reading the question I wondered why I had not personally been bitten by this that I could recall, but seeing this answer I realize that I already use the form f[] the vast majority of the time, inside or outside of DynamicModule. I have for years felt that this is superior in general as it allows passing Symbol names without unexpected evaluation, and because to me it better follows the apparent paradigm of the language. I personally quite dislike the exceptions such as Quit that have action as bare Symbols. IMHO f[] should be the guideline everywhere. $\endgroup$ – Mr.Wizard Jul 27 '16 at 16:35
  • $\begingroup$ A post related to my thoughts above: (32202) $\endgroup$ – Mr.Wizard Jul 27 '16 at 17:11
  • $\begingroup$ @Mr.Wizard Yep, this also helps with accidental reloading (Get) of packages. Where otherwise delayed OwnValues could destructively interfere. $\endgroup$ – Kuba Jul 27 '16 at 19:59

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.