19
$\begingroup$

Whenever I run the code

a = 0;
code := (a++);
Table[code; a, {1000}]

I get a list of 1000 zeros. However, if I replace 1000 with 100, then a get a list equal to Range[100]. Is this a bug or am I missing something?

$\endgroup$
3
  • $\begingroup$ I get the same behavior (Mac OS X, MMA 11.2). The phenomenon seems to switch at 249/250. $\endgroup$
    – Cassini
    Commented Oct 19, 2017 at 12:56
  • $\begingroup$ I get: n <= 249 gives Range[249]. n > 250 gives 250 zeros. (Win10, MMA 11.2) $\endgroup$ Commented Oct 19, 2017 at 12:56
  • 1
    $\begingroup$ I get the same behavior with versions 5.2 and 8.0.4 on Windows 7 x64. $\endgroup$ Commented Oct 19, 2017 at 14:56

1 Answer 1

32
$\begingroup$

This is because Table automatically compiles its argument above a certain length limit.

SystemOptions["CompileOptions" -> "TableCompileLength"]
(* {"CompileOptions" -> {"TableCompileLength" -> 250}} *)

It does not seem to realize that the code modifies global variables because that behaviour is hidden behind code. Notice that the following both work fine:

Table[a++; a, {1000}]
Clear[code]
a = 0;
code[] := (a++);
Table[code[]; a, {1000}]

I would call this behaviour "a bug", but at the same time I would advise to try to stick to conventions. Do not define a symbol in such a way that its evaluation has side effects, at least not without good reason. This is not only confusing to the auto-compiler, it is also confusing to people who read your code.

$\endgroup$
1
  • 4
    $\begingroup$ Really helpful explanation! So ... shd this question get a bug tag? $\endgroup$
    – Alan
    Commented Oct 19, 2017 at 16:44

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.