8
$\begingroup$

Here is a (vicious) problem I am able to reproduce with v12 and v11.3 (previous versions not tested) and OSX.

This is a minimal example to demonstrate it (even if it seems useless here I do need Dynamic to display results in real time in some more complicated code) and which triggers for me a continuous max cpu load :

DynamicModule[{searchstring = "tr"},
 (* InputField[Dynamic[searchstring, ...]]*)
 {<|"aa" -> 1, 
     "bb" -> 1|>, <|"aa" -> 2, "bb" -> 2|>} // 
   Query[Select[#"aa" < 2.*StringLength@searchstring &]] // Dynamic
 ]

while the following don't trigger it :

(Here i get rid of Query and use the operator form of Select):

DynamicModule[{searchstring = "tr"},
 (* InputField[Dynamic[searchstring, ...]]*)
 {<|"aa" -> 1, 
     "bb" -> 1|>, <|"aa" -> 2, "bb" -> 2|>} // 
   Select[#"aa" < 2.*StringLength@searchstring &] // Dynamic
 ]

or

(here i just get rid of the constant 2. which multiplies StringLength !)

DynamicModule[{searchstring = "tr"},
 (* InputField[Dynamic[searchstring, ...]]*)
 {<|"aa" -> 1, 
     "bb" -> 1|>, <|"aa" -> 2, "bb" -> 2|>} // 
   Query[Select[#"aa" < StringLength@searchstring &]] // Dynamic
 ]

Do you observe the same ? Any idea what is wrong ?

$\endgroup$
  • 1
    $\begingroup$ I observed the same think on Windows 10 / Mathematica 12. I confirmed with LinkSnooper that your first command creates a constant communication between the front end and the kernel. Also, when I removed the multiplication, the problem does not happen. I don't know why it happens, but it looks like it is the Kernel that is constantly telling the FrontEnd to refresh. $\endgroup$ – Gustavo Delfino May 2 at 17:52
  • $\begingroup$ Actually it looks like the problem appears as soon as you do any arithmetics (+-*/^) with the dynamic variable : DynamicModule[{number = 12}, {<|"aa" -> 1, "bb" -> 1|>, <|"aa" -> 2, "bb" -> 2|>} // Query[Select[#"aa" < number^2 &]] // Dynamic ] $\endgroup$ – SquareOne May 2 at 20:24
  • $\begingroup$ p.s. I'd report it to WRI Support. $\endgroup$ – Kuba May 3 at 13:00
8
$\begingroup$

A quick fix is to add TrackedSymbols :> {searchstring} to the Dynamic.

But at the end it is just another example from a neverending series "Dynamic does/not fire unexpectedly".

This series taught me to not use Dynamic to calculate things but only to display them. It will be more work on your side but it will dramatically reduce number of headaches.

This is how more or less I do things lately:

DynamicModule[
  {searchstring, viewResults, searchstringSet}
, {
    InputField[Dynamic[searchstring,searchstringSet[#]&], String, ContinuousAction->True]
  , Dynamic[viewResults]
  }
, Initialization:>(
    searchstringSet[val_]:=(
      searchstring=val
    ; viewResults = {<|"aa"->1,"bb"->1|>,<|"aa"->2,"bb"->2|>} // Query[Select[#"aa"<2.*StringLength@searchstring&]]
    )
  ; searchstringSet["tr"]
  )
]
$\endgroup$
  • $\begingroup$ On my computer, under Version 12, your code produces no useful result, i.e., an InputBox with tr in it, which if evaluated reproduces the two Associations with the strings "aa" and "bb". You write that TrackedSymbols is necessary, but it is not in your code. What is this code meant to accomplish, and how does one make it do it? $\endgroup$ – CElliott May 10 at 11:00
  • $\begingroup$ @CElliott works for me v12 Win10. It is meant to do what OP meant it to do, it shows all of associations where aa is greater than the string length of your input. So if you enter e.g. t only the first one should be shown. I didn't say TrackedSymbols is necessary, it was a quick fix for OP's code. But I went with a general solution, not a quick fix. Let me know if something still isn't clear. $\endgroup$ – Kuba May 10 at 11:11
6
$\begingroup$

You may use the TrackedSymbols option on either DynamicModule or Dynamic.

From the comments in the OP the front-end cannot determine when to refresh the dynamic with the usage of the dynamic variable in Query. You can explicitly tell the front-end which variable to track for updates with TrackedSymbols.

DynamicModule[{searchstring = "tr"},
 Dynamic[
  {<|"aa" -> 1, "bb" -> 1|>, <|"aa" -> 2, "bb" -> 2|>} // 
   Query[Select[#"aa" < 2.*StringLength@searchstring &]],
  TrackedSymbols :> {searchstring}]
 ]

Now that the symbols to track have been explicitly provided, the front-end will only refresh the Dynamic when that symbol changes.

Hope this helps.

$\endgroup$
  • $\begingroup$ Thanks for your answer which is the simplest for sure. However I decided to accept Kuba's answer to highlight the problems with dynamics and the valuable answer. $\endgroup$ – SquareOne May 3 at 12:06
  • 1
    $\begingroup$ By the way, is there a reason TrackedSymbols is not an official option for DynamicModule. Given the many problems with the updating, it really should ... $\endgroup$ – SquareOne May 3 at 12:11
  • $\begingroup$ @SquareOne There is nothing Dynamic[] about DynamicModule, so to speak: It does no tracking at all and generates no updating. Only symbols in Dynamic[] wrapped code are tracked. TrackedSymbols only makes sense inside a Dynamic[], whether it is one wrapped automatically around the body of a Manipulate[] or, as per the docs, required outside Refresh[] for Refresh to work properly. $\endgroup$ – Michael E2 May 3 at 15:29
  • $\begingroup$ @MichaelE2 ;) I've just started to use DynamicModule instead of Manipulate and thought that TrackedSymbols would also be an option of that function ! I did not even notice that in the solution given, the option was part of Dynamic. Shame. $\endgroup$ – SquareOne May 3 at 16:05
  • $\begingroup$ @MichaelE2 and I see that Edmund just wrote in his answer that TrackedSymbols is a DynamicModule option also ;) $\endgroup$ – SquareOne May 3 at 16:52

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.