19

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?

bbgodfrey
  • 61,439
  • 17
  • 89
  • 156

1 Answers1

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
  • 234,956
  • 30
  • 623
  • 1,263