I need to label some data in arbitrarily nested ragged lists, with a stream of unique labels. It's very convenient if the labels are consecutive integers, starting at 0 or 1, and if I can produce the same stream every time I label a given data set.

I can do this with recursive functions that thread around the current label in the parameter list and conventionally in every output (say the first element in a list, by convention; this is essentially an explicit simulation of the state monad of Haskell). It's cumbersome and ugly, so I'm looking for a better solution.

Unique comes close to fitting the bill. In a fresh kernel, MMA version 9.0.1 on Mac 10.8.4, consider the following


{$3, $4, $5}

Great. Let's try starting them at 1, following the documentation,

$ModuleNumber = 1; 
Table[Unique[], {3}]

{$6, $7, $8}

Ooops, surprise!

The following, which was my first attempt, produces an internal ENULL bugcheck

Block[{$ModuleNumber = 1},
 Table[Unique[], {3}]]

Mathematica has detected an internal error: vMessage ENULL

Please report this error as soon as possible to [email protected] giving as many details as possible of the circumstances under which it occurred.

I can mimic the entire thing with my own global state variable and mimic of Unique, but thought I'd first check here for insight and advice.

  • 3
    $\begingroup$ I wouldn't play with $ModuleNumber in any case. Who knows what that may break. At the very least, you can break the uniqueness of variables produced by Module, and that can lead to all sort of bugs. $\endgroup$ Jun 26, 2013 at 19:35
  • 1
    $\begingroup$ I understand the warning (and basically agree with it, outside of toys, and I was making a toy). It is interesting that the documentation explicitly states that $ModuleNumber can be reset, even outside a Block. But then, it doesn't actually work :) $\endgroup$
    – Reb.Cabin
    Jun 26, 2013 at 19:38
  • $\begingroup$ Perhaps, redefining $ModuleNumber may have some constructuve uses which I am unaware of. But personally I would not mess with it. $\endgroup$ Jun 26, 2013 at 19:47

2 Answers 2


I would use this solution:

newStream[start_: 1] := Module[{i = start}, i++ &]

s = newStream[];
Table[s[], {5}]
(* Out: {1, 2, 3, 4, 5} *)

s = newStream[20];
Table[s[], {5}]
(* Out: {20, 21, 22, 23, 24} *)

This avoids having a global variable, and you can have many streams at the same time.

  • $\begingroup$ Seems like closure. $\endgroup$
    – Wei John
    Oct 22, 2021 at 5:25

Maybe something along those lines?

nextlabel[] := StringTemplate["`` label"][++lastlabel]

lastlabel = 0;
Table[ nextlabel[], {10} ]
{"1 label", "2 label", "3 label", "4 label", "5 label", "6 label", 
"7 label", "8 label", "9 label", "10 label"} 

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.