# Module does not remove a function definition

The following is a minor variant of the function uniqueTuples as given by Simon Woods in this answer.

g[lists___List] := Module[{f},
f[___, x_, x_,___] := Sequence[];
f[x___] := (f[x]=Sequence[];{x});
Attributes[f]={Orderless};
Flatten[Outer[f, lists], Length[{lists}]-1]]

data=RandomInteger[40, {6,11}];
Length[g @@ data] // Timing
(* {6.177640,388897} *)


In the definition of g we have a local variable f, which is used as a function and for which a lot of DownValues could be created. This function is not removed when the Module is evaluated:

Names["f$*"] (* {f$,f$342} *) Length[DownValues[f$342]]
(* 388899 *)


I am using version 10.0.2 on Windows (32-bit). Indeed, this bug made Mathematica crash due to lack of memory when I used this function a number of times with larger arguments.

g[lists___List] := Module[{f}, f[___, x_, x_, ___] := Sequence[];
f[x___] := (f[x] = Sequence[]; {x});
Attributes[f] = {Orderless, Temporary};
Flatten[Outer[f, lists], Length[{lists}] - 1]]


To address the comments let me put it another way: If you overwrite the attributes of course they are going to be 'lost'

Look at this:

g[lists___List] := Module[{f}, f[___, x_, x_, ___] := Sequence[];
f[x___] := (f[x] = Sequence[]; {x});
Print[Attributes[f]];
Attributes[f] = {Orderless};
Print[Attributes[f]];
Flatten[Outer[f, lists], Length[{lists}] - 1]]

• Thank you very much. This is a nice and useful workaround, but adding the attribute Temporary to a local variable of a Module should be superfluous. – Fred Simons Jan 20 '15 at 10:21
• Ah, I see. It is not a bug in Mathematica, but a subtle error of mine. The solution is to use SetAttributes[f, Orderless]; instead of defining Attributes[f]={Orderless};. Many thanks again. – Fred Simons Jan 20 '15 at 12:13