Google Группы больше не поддерживают новые публикации и подписки в сети Usenet. Опубликованный ранее контент останется доступен.

Tempvar zombies littering my context!

664 просмотра
Перейти к первому непрочитанному сообщению

kj

не прочитано,
4 дек. 2010 г., 06:12:2104.12.2010
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

не прочитано,
5 дек. 2010 г., 21:50:2905.12.2010

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

не прочитано,
5 дек. 2010 г., 21:51:1205.12.2010
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 новых сообщений