Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tempvar zombies littering my context!

663 views
Skip to first unread message

kj

unread,
Dec 4, 2010, 6:12:21 AM12/4/10
to
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

kj

unread,
Dec 5, 2010, 9:50:29 PM12/5/10
to

I discovered a shockingly simple workaround to the problem I reported
in the original post of this thread: just use Block instead of
Module!

n[1]:= a[b_] := Block[{c, d},


c[___] := (Print[c];);
d[___] := (Print[d];);
c[];
d[] /; b === 1

];

In[2]:= a[1];
During evaluation of In[2]:= c

During evaluation of In[2]:= d

In[3]:= a[2];
During evaluation of In[3]:= c

In[4]:= Names[$Context <> "*"]
Out[4]= {"a", "b", "c", "d"}


(Granted, this may be only a workaround rather than a full solution.
It all depends on whether what I reported originally was "a bug or
a feature". If it was a bug (and an undocumented behavior of
lingering tempvar zombies sure looks like a bug to me), then the
fix can be done only by Wolfram's personnel.)

As an unexpected bonus, this solution *also* fixes something that
was a minor vexation: the extra junk (e.g. $1234) at the end of
variable names printed from within Module.

This is a rare occurrence indeed: a fix to one problem that also
fixes another problem that was (at least in my mind) entirely
unrelated to the first one.

~kj

brien colwell

unread,
Dec 5, 2010, 9:51:12 PM12/5/10
to
I had a similar issue and the solution was to use Block not Module.
I'm rather lost on the distinction between the two.


On Sat, Dec 4, 2010 at 6:12 AM, kj <no.e...@please.post> wrote:
> 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"}

0 new messages