13

I need a lot of Internal`Bags so I made them with Table. It works fine for 249 or fewer Bags but goes horribly wrong for 250 or more:

Table[Internal`Bag[0], {i, 249}]
(* {Internal`Bag["<" 1 ">"], ... } *)

Table[Internal`Bag[0], {i, 250}]
(* {0, 1, 2, ..., 249} *)

What's causing this weird behavior and how can I avoid it?

xzczd
  • 65,995
  • 9
  • 163
  • 468
Chris K
  • 20,207
  • 3
  • 39
  • 74

1 Answers1

17

Seems to be the same underlying issue as here: by default, Table compiles its argument when the number of values is 250 or more. Evidently Internal`Bag doesn't like this!

If all Internal`Bags are the same, then

ConstantArray[Internal`Bag[0], 250]

seems to work.

Otherwise, temporarily changing the TableCompileLength system option works:

tcl = SystemOptions["CompileOptions" -> "TableCompileLength"];
SetSystemOptions[
  "CompileOptions" -> {"TableCompileLength" -> \[Infinity]}];
Table[Internal`Bag[0], {i, 250}]
SetSystemOptions[tcl];

Perhaps, a general heuristic: if anything starts breaking or slowing down at 250, suspect behind-the-scenes Compilation. See here, here, here, and here for more examples.

Chris K
  • 20,207
  • 3
  • 39
  • 74
  • 1
    The default return value for Internal`Bag from Compile is the bag ID or something That would be my assumption for what's breaking. Better than the return value from NIntegrate`Heap (which it can't return even though it can use in compiled code). – b3m2a1 Jul 28 '19 at 17:08
  • 3
    As you are temporarily(!) modifying system settings, I would recommend wrapping your business in Internal`WithLocalSettings[], as was done here. – J. M.'s missing motivation Jul 29 '19 at 03:19