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