Strange behavior of Table

19

2

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?

Antonio De Juárez

Posted 2017-10-19T12:45:30.167

Reputation: 301

I get the same behavior (Mac OS X, MMA 11.2). The phenomenon seems to switch at 249/250. – Cassini – 2017-10-19T12:56:07.060

I get: n <= 249 gives Range[249]. n > 250 gives 250 zeros. (Win10, MMA 11.2) – aardvark2012 – 2017-10-19T12:56:24.563

1I get the same behavior with versions 5.2 and 8.0.4 on Windows 7 x64. – Alexey Popkov – 2017-10-19T14:56:03.370

Answers

32

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.

Szabolcs

Posted 2017-10-19T12:45:30.167

Reputation: 213 047

4Really helpful explanation! So ... shd this question get a bug tag? – Alan – 2017-10-19T16:44:22.810