Tempvar zombies littering my context!
- To: mathgroup at smc.vnet.net
- Subject: [mg114424] Tempvar zombies littering my context!
- From: kj <no.email at please.post>
- Date: Sat, 4 Dec 2010 06:12:21 -0500 (EST)
I discovered that defining a Module in a certain way causes results
in lingering temporary variable "zombies".
To best show this, first I'll present a simple, zombie-free module:
In[1]:= a[b_] := Module[{c, d},
c[___] := (Print[c];);
d[___] := (Print[d];);
c[];
d[]
]
This works as expected:
In[2]:= a[1];
During evaluation of In[2]:= c$6797
During evaluation of In[2]:= d$6797
Also, the names in the context are as expected; in particular,
there are no temporaries in it:
In[3]:= Names[$Context <> "*"]
Out[3]= {"a", "b", "c", "d"}
The above is what I'd consider "standard operating procedure."
Now, before proceeding to the weirdness, I clear the context, for
good measure:
In[4]:= Scan[Remove, Names[$Context <> "*"]]
...and define another module, identical to the first one, except that
in this one I've added a condition to the last line:
In[5]:= a[b_] := Module[{c, d},
c[___] := (Print[c];);
d[___] := (Print[d];);
c[];
d[] /; b === 1
]
The module's behavior is, again, as expected:
In[6]:= a[1];
During evaluation of In[6]:= c$6798
During evaluation of In[6]:= d$6798
The weirdness is in the context's names:
In[7]:= Names[$Context <> "*"]
Out[7]= {"a", "b", "c", "c$", "d", "d$", "d$6798"}
Now we have lingering temporary variable zombies! Not only
"stubs" (is this what they're called) like c$ and d$, but also a
full-blown d$6798. Here are their definitions:
In[8]:= {#, ToString[Definition[#]]} & /@
Select[%, MemberQ[Attributes[#], Temporary] &] // ColumnForm
Out[8]= {"c$", "Attributes[c$] = {Temporary}"},
{"d$", "Attributes[d$] = {Temporary}"},
{"d$6798", "Attributes[d$6798] = {Temporary}\n \nd$6798[___] := (Print[d$6798]; )"}}]
FWIW, the zombies appear only when the condition in the last line
is True (leading to the evaluation of the rest of the last line):
In[9]:= a[2];
During evaluation of In[9]:= c$6799
In[10]:= Names[$Context <> "*"]
Out[10]= {"a", "b", "c", "c$", "d", "d$", "d$6798"}
Note that after evaluating a[2] we see no zombie for d$6799.
Nevertheless, every time the condition is true, the context gets
littered with one more zombie:
n[11]:= a[1];
During evaluation of In[11]:= c$6800
During evaluation of In[11]:= d$6800
In[12]:= Names[$Context <> "*"]
Out[12]= {"a", "b", "c", "c$", "d", "d$", "d$6798", "d$6800"}
What's going on? And, more importantly, how can I redefine the
module in In[5] so that its behavior remains unchanged, but it does
not litter the context with a trail of zombies?
Thanks!
~kj