4
$\begingroup$

Let' s consider this packege :

BeginPackage["myProgram`"];
myProgramF::usage = "arg + 1";
Begin["`Private`"];
myProgramF[arg_: 0] := arg + 1;
End[];
EndPackage[];

Invoked by :

Needs["myProgram`", packageFile];
myProgramF[1]

it works as expected.

Obviously, instead this code generate an error myProgramF::shdw :

Block[{myProgramF},
 Needs["myProgram`", packageFile];
 myProgramF[1]
 ]

Surprisingly this generate an error also

Block[{},
 Needs["myProgram`", packageFile];
 myProgramF[1]
 ]

And

Module[{},
 Needs["myProgram`", packageFile];
 myProgramF[1]
 ]

does too.

Clearly, I' m missing something about the variable shadowing. Please, can you suggest what?

$\endgroup$
5
$\begingroup$

Symbols are created at the instant that they are read -- not when they are evaluated.

In the first example, there are two expressions: Needs[...]; and myProgramF[...]. The first expression is read and evaluated, loading the package. The second expression is then read, resolving myProgramF using the loaded package. It is then evaluated.

In the second example, there is only one expression Block[...]. First it is read. Since the package has not been loaded yet, myProgramF will be resolved in the Global` context. The expression is only evaluated after it has been fully read. The evaluation causes the package to load, triggering the shadowing warning.

The third (Block[...]) and fourth (Module[...]) examples behave in the same way as the second: the expressions are read completely before the package is loaded.

End-of-Line Subtlety

The first example also contains a subtlety in its own right. One might think that it is a single expression consisting of a CompoundExpression, i.e.

CompoundExpression[Needs["myProgram`", packageFile], myProgramF[1]]

But it is not. Rather, it is two expressions like this:

CompoundExpression[Needs["myProgram`", packageFile], Null]
myProgramF[1]

The Mathematica reader always takes a conservative approach when reading. Once it reaches the end of a line, it will stop reading if the expression read so far is a complete expression. That is why we get two expressions in the first example, but each of the other examples have only one expression.

If the first example had been written like this:

Needs["myProgram`"]; myProgramF[1]

... then it would be read as a single expression and would cause the shadowing warning that we see in the other examples.

Aside

Incidentally, it is because of this conservative reading strategy that we cannot write expressions like this:

myFunction
  [ bigLongExpressionInvolving[argument1]
  , argument2 + anotherBigLongExpression
  , argument3
  ]

... not that any sane person would want to write code like that, of course ;D

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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