7

I was playing around with $NewSymbol trying to find something to answer this question with. The docs say that

$NewSymbol is applied before the symbol is actually created. If the action of $NewSymbol causes the symbol to be created, perhaps in a different context, then the symbol as created will be the one used.

So I tried to automatically move a particular new symbol into a test context which should prevent its creation in the Global`* context, but the symbol gets created in both contexts.

In[1]:= Remove["Global`*"]
In[2]:= $NewSymbol=(Print[#1," : ",#2];
                    If[#1==="aLongTestSymbolName"&&#2==="Global`",
                       Symbol["TestContext`"<>#1]])&;

In[3]:= x
During evaluation of In[3]:= x : Global`
Out[3]= x

In[4]:= aLongTestSymbolName
During evaluation of In[4]:= aLongTestSymbolName : Global`
During evaluation of In[4]:= aLongTestSymbolName : TestContext`
Out[4]= aLongTestSymbolName

In[5]:= Names["Global`*"]
Out[5]= {aLongTestSymbolName,x}

In[6]:= Names["TestContext`*"]
Out[6]= {TestContext`aLongTestSymbolName}

I believe that "aLongTestSymbolName" should not be in the Global` context. Can anyone see what I've done wrong or if I've misinterpreted the documentation?


Note: Having the symbol created in both contexts is not an option for the automatic highlighting in the above linked to question. The idea is to reserve certain symbol names such as "x"~~___ for variables and "f"~~___ for functions and then use string patterns in $NewSymbol to move the symbols to the appropriate highlighted context.

Community
  • 1
  • 1
Simon
  • 14,631
  • 4
  • 41
  • 101

2 Answers2

3

That is because you passed the symbol name to Print, which immediately made the symbol in Global`. :-)

Or not. I should really try things before answering, but I thought I knew this one. Oops.


It seems to me now that $NewSymbol does not intercept the creation of a symbol, or if it does, how to make use of that is not clear.

If one uses:

$NewSymbol = Print["Name: ", #2, #] &;

then:

In[10]:= aNewSymbol

During evaluation of In[10]:= Name: Global`aNewSymbol

Out[10]= aNewSymbol

We see that $NewSymbol does not work like $PrePrint in that its output does not become the expression.

Therefore, if we use:

$NewSymbol = Symbol["TestContext`" <> #] &;

aSecondSymbol

aSecondSymbol is merrily created in Global` as though nothing had changed.

If $NewSymbol can be used to direct the context in which the symbol is created, as the documentation states, it is not clear to me how this may be done.

Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • 3
    W - Actually, in your example `aSecondSymbol` is created in both `` Global` `` and `` TestContext` ``. Do you think the documentation is wrong then? Maybe it worked in an older version but got broken and no one noticed... I guess I should ask WRI. – Simon May 29 '11 at 22:45
  • @Simon, that's correct. My point was that it is still created in ``Global` `` apparently completely independently from anything that is invoked by `$NewSymbol`, and that `Print` / `If` etc. are unrelated to the problem. I hope that Michael, Daniel, or Sasha will stop by with an answer. – Mr.Wizard May 30 '11 at 07:58
  • It doesn't look like one of our local friendly WRI employees has stopped by - so I sent a bug report to WRI. – Simon May 30 '11 at 22:42
  • @Simon Have you got any response from WRI? – Alexey Popkov Aug 17 '11 at 06:51
  • @Alexey: My email was added to an existing bug report. We might hear more when v9 is released... – Simon Aug 17 '11 at 11:02
0

In this Mathematica Journal article about context issues you may find that just the presence of a new symbol in the parsing phase of the evaluation will add this symbol to the current context. In this case aLongTestSymbolName is handed to the Print and If as #1 and is therefore created in the current context Global`. I don't think there is anything you can do in the $NewSymbol function to prevent this.

The article mentions that even if you use Begin["Context1`"]; someSymbol; End[] someSymbol is not placed in the Context1` context unless Begin["Context1`"] is evaluated on a separate line.

Sjoerd C. de Vries
  • 16,122
  • 3
  • 42
  • 94
  • see the answer I just undeleted. I think it's not right, because the symbol and context names are passed as strings, according to the documentation. – Mr.Wizard May 29 '11 at 21:15
  • @Mr.Wiz hmmm, yerright. Perhaps mma does something similar to a ToString[symbol] before passing? That would then create the symbol. – Sjoerd C. de Vries May 29 '11 at 21:55
  • 1
    The docs say that $NewSymbol is evaluated before the symbol is created. I imagine that new symbol code is called by `MakeExpression` when it encounters a unknown string. But before it creates the symbol it runs $NewSymbol with that string as an argument. – Simon May 29 '11 at 22:36