How symbol lookup actually works

This behaviour has changed since that book was published. I am writing this additional answer to make it clear how Mathematica 9 searches contexts for symbols and that even the current version 9 documentation is incorrect in describing this.

How symbol lookup actually works

When you enter a symbol name such as x, Mathematica will check if a symbol with this name already exists. It will first search the contexts from $ContextPath for x, one by one. If it doesn't find it there, it'll search the context from $Context for it. If it still doesn't find it, then it will create a new symbol named x in $Context.

Thus $ContextPath controls where to look for symbols, while $Context controls where to create new symbols.

Your observations are explained by these rules, noting that Begin will change $Context only but not $ContextPath. Note that BeginPackage will change both $Context and $ContextPath.

Warning: the documentation contains an error in Mathematica versions older than 11.3.

The $ContextPath documentation states that

$ContextPath is a global variable that gives a list of contexts, after $Context, to search in trying to find a symbol that has been entered.

In fact $ContextPath is searched before $Context in the current version.

In old versions this was not the case, as the Wagner book describes. I don't know when the change happened.

The Contexts tutorial does correctly state the order of search in the current version:

Since $Context is searched after $ContextPath, you can think of it as having "." appended to the file search path.


Not an answer. Just screen shot. I booted up version 2.2 to verify the book result. And it does verify:

screenshot

The same result we get with version 5.2:

screenshot


Something changed since the book was written (screenshot from version 9 follows):

screenshot


It appears since version 3 shadowed variables are given priority, as demonstrated below. In the temp` context x is taken as temp`x unless Global`x exists.

Remove[temp`x, Global`x]
temp`x = 6;
Begin["temp`"];
{x, Global`x}
End[];

{6, x}

Remove[temp`x, Global`x]
temp`x = 6;
x = 5;
Begin["temp`"];
{x, Global`x}
End[];

{5, 5}