3

Good day,

Consider the following:

In[1]:= HoldComplete[With[{line=a},Null]]
Names["`*"]
Attributes/@Names["`*"]
Remove/@Names["`*"]
Out[1]= HoldComplete[With[{line=a},Null]]
Out[2]= {a,line,line$}
Out[3]= {{},{},{Temporary}}
During evaluation of In[1]:= Remove::rmnsm: There are no symbols matching
"line$". >>
Out[4]= {Null,Null,Null}

One can see that Remove::rmnsm message appear although the temporary Symbol line$ still exists up the that moment. Why this happens?

P.S. I am using Mathematica 7.01. In v.5.2 this message does not appear.

Alexey Popkov
  • 9,355
  • 4
  • 42
  • 93

1 Answers1

3

I think what is happening is when you remove the Symbol line then there are no further references to the temporary variable line$ and so it is automagically removed.

In[1]:= HoldComplete[With[{line=a},Null]]
        Names["`*"]
        Attributes/@Names["`*"]
Out[1]= HoldComplete[With[{line=a},Null]]
Out[2]= {a,line,line$}
Out[3]= {{},{},{Temporary}}

In[4]:= Remove["line"]

In[5]:= Names["`*"]
Out[5]= {a}

This was tested in Mma v8. So maybe the reference counting (or the implementation of localization) has changed slightly since v5?

Note that if you try to remove the temporary symbol first, you get quite an informative warning:

In[6]:= HoldComplete[With[{line=a},Null]]
        Names["`*"]
        Attributes/@Names["`*"]
        Remove/@Reverse@Names["`*"]
Out[6]= HoldComplete[With[{line=a},Null]]
Out[7]= {a,line,line$}
Out[8]= {{},{},{Temporary}}
During evaluation of In[6]:= Remove::relex: Cannot remove lexical symbol 
   line$ except automatically (when line is removed). >>
Out[9]= {Null,Null,Null}
Simon
  • 14,631
  • 4
  • 41
  • 101
  • Thank you for the explanation. In version 5.2 the symbol `line$` is not created: ``Hold@Evaluate@With[{line = a}, Names["`*"]]`` gives `Hold[{"a", "line"}]` while in version 7.01 it gives `Hold[{"a", "line", "line$"}]`. But without `Hold` or `HoldComplete` *Mathematica* 7.01 does not create the symbol `line$`. Why? – Alexey Popkov Apr 19 '11 at 09:15
  • I think that maybe `With` always creates such variables, but they are removed upon its normal termination. If something (such as `Hold` or `Trace`) stops the `With` from proceeding as normal then the temporary variable is not removed. But hopefully someone from WRI will come along and say what's really going on.... – Simon Apr 19 '11 at 10:54
  • @Alexey when I evaluate ``Hold@Evaluate@With[{line = a}, Names["`*"]]`` from a fresh kernel, I get: `Hold[{"a", "line"}]` – Mr.Wizard Apr 19 '11 at 15:51
  • @Mr.Wizard That was my mistake. `Hold@With[{line = a}, Null]; Names["`*"]` gives `{"a", "line", "line$"}`. – Alexey Popkov Apr 19 '11 at 18:23
  • @Alexey, on a clean kernel ``Hold@With[{line = a}, Null]; Names["`*"]`` gives me ``{"a", "line"}`` – Mr.Wizard Apr 19 '11 at 18:27
  • @Mr.Wizard There is something strange: it seems that this behavior depends on the presence of `;` after the first expression. Moreover it sometimes behaves differently in the first and the second evaluation: ``{Hold@With[{line = a}, Null], Names["`*"]}`` gives `{Hold[With[{line = a}, Null]], {"a", "line", "line$"}}` only for the second evaluation. I do not understand the reason. – Alexey Popkov Apr 19 '11 at 18:37