# Checkbox behaving weird when variables are local

I have a DynamicModule in which I need a checkbox with a Max in the dynamic part:

Checkbox[Dynamic[... Max ...]]


After removing everything else from the DynamicModule, it still behaves badly: (whether q[[1, 1]] is false or true, the checkbox shows a big square, although q[[1,1]] doesnt have a bad value):

DynamicModule[{s = 1, q = {{False}}},
{Checkbox[Dynamic[q[[1, 2 - Max[s, 0]]]]], Dynamic[q[[1, 2 - Max[s, 0]]]]}]


If variables aren't local, it behaves well:

s = 1; q = {{False}};
Checkbox[Dynamic[q[[1, 2 - Max[s, 0]]]]]
Dynamic[q[[1, 2 - Max[s, 0]]]]

-

This appears to be a front-end bug involving the evaluation of arrays and built-in functions within a DynamicBox. The original example can be made to work by defining max = Max; and using the user function max in place of the built-in functionMax:

max = Max;
DynamicModule[{s = 1, q = {{False}}},
{Checkbox[Dynamic[q[[1, 2 - max[s, 0]]]]], Dynamic[q[[1, 2 - max[s, 0]]]]}]


Here is a screenshot showing the original example and the work-around:

The work-around also responds to mouse clicks properly.

An alternative that does not rely on the global function definition max is to "hide" the built-in function Max by writing Max[##]& instead:

DynamicModule[{s = 1, q = {{False}}},
{Checkbox[Dynamic[q[[1, 2 - Max[##]&[s, 0]]]]], Dynamic[q[[1, 2 - Max[##]&[s, 0]]]]}]


Analysis

As evidence for the claim that this is a bug, consider the following evaluations (tested under Mathematica versions 7, 8 and 9 on Windows, 64-bit). The problem can be exhibited by direct generation of DynamicBox structures, taking out of the picture all of the complex "double-evaluation" and "demodularization" processing done by DynamicModule.

Here is a trivial use of DynamicBox:

RawBoxes @ DynamicModuleBox[{q = {0}}, DynamicBox @ ToBoxes @ q[[1]]]
(* 0 *)


The result is a cell that displays the value 0. However, observe the puzzling behaviour that occurs when q[[1]] is changed to q[[Max@1]]:

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Max@1]]]
(* List *)


For some reason, the result shows List instead of 0. Some other built-in functions, such as Sqrt and Sin fail in similar fashion:

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Sqrt@1]]]
(* List *)

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Sin@1]]]
(* List *)


But other functions, such as Abs, Plus and Identity do not:

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Abs@1]]]
(* 0 *)

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Plus@1]]]
(* 0 *)

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Identity@1]]]
(* 0 *)


User-defined functions behave properly, even when they are implemented in terms of built-in functions that do not:

max = Max;
RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[max@1]]]
(* 0 *)

RawBoxes @ DynamicModuleBox[{q={0}}, DynamicBox @ ToBoxes @ q[[Max[##]&@1]]]
(* 0 *)


It would appear that some built-in kernel evaluation rules or array reference optimizations are not compatible with dynamic boxes. Perhaps the front-end rendering code is failing to take such cases into account.

-
I have sent a bug report to WRI. –  WReach May 10 '14 at 17:08
This bug still persists in V10 (on OS X 10.9.4 at least) –  Mike Honeychurch Jul 16 '14 at 2:37

I have no idea, I hope this work-around will help you until someone competent posts an answer.

DynamicModule[{s, q, z},
{
Checkbox[ Dynamic[z, (z = q[[1, 2 - Max[s, 0]]] = #) &]],
Dynamic[q[[1, 2 - Max[s, 0]]]]
},
Initialization :> (s = 1; q = {{z = False}};)]

-