7
$\begingroup$

This question already has an answer here:

In a notebook with a new kernel, execute the following in an Input cell:

$Context
Begin["Test`"];
$Context
f = x \[Function] x*x;
f[2]
End[];
$Context
f[2]  (* why is this recognized 2nd time?? *)
Test`f[2]

The result is as expected (i.e., f[2] is unevaluated in the Global context). But now evaluate the same Inpute cell, without any changes. The contexts are reported as before, but this time f[2] evaluates to 4 in the Global context. Why?

$\endgroup$

marked as duplicate by Kuba, Yves Klett, Feyre, xyz, m_goldberg Sep 13 '16 at 11:25

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ The f[2] that is followed by the comment returns unevaluated, as it should. Then, Test f[2] returns evaluated, as it should. What is the issue? $\endgroup$ – bbgodfrey Sep 13 '16 at 3:51
  • 2
    $\begingroup$ The second evaluation is different from the first, because Global`f is already created, so you are assigning to it, instead of Test`f. $\endgroup$ – ilian Sep 13 '16 at 4:20
8
$\begingroup$

There are two things that influence symbol lookup: $ContextPath and $Context. This is described in:

In short: $ContextPath controls where the system looks for existing symbols. This search is done first. $Context controls where new symbols are created if a name was not found in $ContextPath any contexts.

Begin changes only $Context. BeginPackage changes both $ContextPath and $Context.

You are only using Begin, but not BeginPackage. This means that $Context will be set to "Test`" but $ContextPath will stay what it was before.

When you mention a symbol name such as f, the first thing Mathematica does is that it looks for it in the contexts contained in $ContextPath. If it is found there, it uses that instance. This is what happens during the second evaluation: f is found in Global`, so f now refers to Global`f, not Test`f.

Why does f exist in Global`? Because you mentioned it when evaluating f[2]. Note the distinction between the fact that a symbol exists and that a symbol has associated definitions. Just evaluating sym alone will create that symbol.

$\endgroup$
  • $\begingroup$ So do you think I should retract a close vote? $\endgroup$ – Kuba Sep 13 '16 at 9:46
  • $\begingroup$ @Kuba As you wish, I am uncertain. The information there was necessary, but I thought it wasn't quite sufficient ... but then I notice that ilian explained this (very tersely) in this comment, so maybe that would have been enough? $\endgroup$ – Szabolcs Sep 13 '16 at 9:48
  • $\begingroup$ We can do both, with this answer we can mark this topic as a duplicate in future anyway. In case where original one isn't clearly answering OP. $\endgroup$ – Kuba Sep 13 '16 at 9:50
  • $\begingroup$ While your answer is simple and helpful, the existing situation is complex and confusing. Iiuc, the behavior I expected matches the current documentation (both online and the documentation that ships with Mma v11) of $ContextPath, and indeed was the actual behavior until v6. Am I correct that due to this behavior change one should effectively never use Begin .. End without nesting it in BeginPackage .. EndPackage? $\endgroup$ – Alan Sep 13 '16 at 12:20
  • 1
    $\begingroup$ @Alan a workaround is to use `f, as it forces f to be in the local context. $\endgroup$ – rcollyer Sep 13 '16 at 13:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.