Checking the context of a fresh variable inside Begin-End, it gives the enclosing context.

In[1]:= Begin["ctx`"];

In[2]:= Context[a]

Out[2]= "ctx`"

In[3]:= End[];

Using the variable name a as function definition in global namespace, it fixes the context to global.

In[1]:= f[a_] := a

In[2]:= Begin["ctx`"];

In[3]:= Context[a]

Out[3]= "Global`"

In[4]:= End[];

I find this very strange. In the function definition f[a_] := a the variable a is bound to the definition. The definition does not determine any value of a, but somehow it pollutes the context it belongs to. Can anyone tell me what is happening here?


1 Answer 1


In the function definition f[a_] := a the variable a is bound to the definition

No, it's not. There is nothing like binding or scoping in the sense that you're talking about. The expression f[a_] := a isn't even really a function definition. It's just an expression. It needs to be evaluated to have any impact, any meaning. In the process of evaluating expressions, the evaluator encounters symbols. The first time it encounters a symbol, it has no information about it, so it can't make assumptions. In particular, it can't know the symbol's intended "scope". But it definitely needs to remember that symbol so it can do the right thing when it encounters it again. Contexts come into play as a way to organize this symbol "dictionary" (pretty much just by using naming conventions), but I think this is a bit of a red herring. The main point is that f[a_] was "seen" by the evaluator, and so (assuming this was the first time) the f and the a get added to the "dictionary", because it needs to remember them. So, what gets "bound" is a new value in DownValues for the symbol f. If we evaluated g[a_] := 2 a, we don't get a new a. But because of the way SetDelayed works, and because of the way the evaluator uses the DownValues it knows about, this apparent name collision doesn't actually collide.

  • $\begingroup$ OK, so f[a_] := a is just a SetDelayed term that takes two parameters f[a_] and a, each a pattern term and variable a term respectively. And when the kernel evaluates the SetDelayed term it assigns some meaning to f. As kernel does, it sees a on the right-hand side it registers to the known dictionary and a is bound to global context. Thanks for clarification. $\endgroup$ Commented Apr 30, 2023 at 16:02
  • $\begingroup$ It also sees a on the left hand side. I don't know which it interprets first, but I would assume the one on the left. $\endgroup$
    – lericr
    Commented Apr 30, 2023 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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