# Why is a symbol still found after changing its context?

It seems that we can change the context of symbols:

In[1]:= x = 1
Out[1]= 1

In[2]:= Context[x] = "foo";

But then x is still interpreted as foox (and not Globalx) even though foo is not in $ContextPath. In[3]:= x Out[3]= 1 In[4]:= foox Out[4]= 1 The behaviour is not consistent though. At other times I randomly get this when evaluating the same sequence of expressions in a new kernel: In[1]:= x = 1 Out[1]= 1 In[2]:= Context[x] = "foo"; In[3]:= x Out[3]= x In[4]:= foox Out[4]= 1 I see this random, erratic behaviour in M9, 10 and 10.1. In M8, x is not seen any more as soon as its context is changed, i.e. it behaves as one would expect. Questions: • Why the random behaviour? • Is it documented or discussed anywhere that Context an be changed? • As for 2: I have not seen mentions of this in the docs, but this has certainly been noticed and discussed here on SE before. In particular, I made use of this effect here, where also the comments below that answer refer to earlier discussions regarding this topic. In fact, those comments also mention the first point in your question, although give no answer for it. – Leonid Shifrin Apr 2 '15 at 23:35 • I seem to recall a detailed discussion in a question here a year or so ago... will try and find it. Interesting question, +1! – ciao Apr 3 '15 at 0:12 ## 2 Answers I think this is a caching problem. Considering the examples in the Update documentation it certainly makes sense that this could be the case. Although Update appears to have no effect I have found something that does: Information. x = 1; Context[x] = "foo"; x foox Context[x] 1 1 "foo" ?x foox x=1 x foox Context[x] x 1 "Global" • On my system this is reliable; I get the same output every time I run it. • Rather surprisingly Information returns the definition for foox but after it is used, such as if it is used again, x points to Globalx. • It does not seem to matter if x is involved; I can for example replace ?x with ?Plus in the lines above and it behaves the same way. • Interestingly, Update with any invalid argument also seems to work (so Update["hello world"] works, but neither Update[] nor Update[Unevaluated@x] nor Update with any function related to symbols, expressions or context I've tried). – celtschk Oct 22 '15 at 9:36 • @celtschk Interesting observation; thanks for the note! Do you have any hypothesis as to why this works? Do you think it's just random behavior? – Mr.Wizard Oct 29 '15 at 3:04 • From further tests, it seems that everything generating a message works; not only Update[""] but also 1/0. Anyway, I now noticed something different: My previous tests had all been by directly entering into the kernel; now I tried in the notebook, and there the context assignment seems to work immediately. – celtschk Oct 29 '15 at 19:28 No erratic behavior on my computer M9. However a simple workaround could be considered that achieves its purpose. Workaround for moving a symbol from one context to another can be achieved by: For example, create symbol in the context Global and move it to foo x = 1; (*create x in Global *) foox = x; (*create x in foo and copy Globalx *) Remove @ x (*remove x from Global it will only exist in foo*) {x, foox} (* {x,1} *) Moving it back to Global x=foox; Remove @ foox {x,foox} (* {1,foox} *) PS: If you don't know ask the penguins...hi,hi,hi • No, this is not a bug, it's an undocumented feature. There are many symbols that behave like this. Begin simply sets$Context and is unrelated to what I was talking about in the question, i.e. changing the context of an existing symbol. "$ContextPath is only for searching for symbols not found within Contexts[]" <-- this is plain incorrect. – Szabolcs Apr 3 '15 at 1:17 • Your are right, I meant$Context instead of Context[], sorry for mistake. I have corrected – penguin77 Apr 3 '15 at 10:24
• @ Szabolcs, sorry if haven't understood your question correctly – penguin77 Apr 3 '15 at 12:02
• This is a way to copy the definition of variable in very simple cases to a new symbol, but copying is not the same as changing the context of the symbol. But fortunately I do not need this, I was just trying to understand how it works. :-) So why is it not the same? Because x may have been referenced somewhere. Consider a=x. Now a points to Globalx . After Context[x]="foo", a will point to foo`x. If x is Removed, then this is not the case any more. – Szabolcs Apr 3 '15 at 14:14
• Another thing to point out that this sort of copying only works in the very simplest of cases. It won't work if x:=1+1. It also won't work if x=b; b=1, or if x has DownValues, Attributes, or other properties ... There's a question about how to reliably copy definitions here. – Szabolcs Apr 3 '15 at 14:17