1
$\begingroup$

The following code prints a message about a symbol in multiple contexts (MMAv9).

BeginPackage["`A`"];
f1[n_] := NotebookDirectory[n];
EndPackage[];
BeginPackage["`B`"];
f2[n_] := NotebookDirectory[n];
EndPackage[]

In contrast, the following code runs as expected.

BeginPackage["`A`"];
f1[n_] := Plus[n];
EndPackage[];
BeginPackage["`B`"];
f2[n_] := Plus[n];
EndPackage[]

Does this happen in newer MMA versions too?

$\endgroup$
  • $\begingroup$ Please don't use the bugs tag when posting new questions. It is meant to be added by someone else than the original poster (see description). $\endgroup$ – Szabolcs Jan 21 '18 at 17:23
  • $\begingroup$ @Szabolcs, I've changed the tag to evaluation. Is there a better tag though? $\endgroup$ – Hector Jan 21 '18 at 17:54
3
$\begingroup$

This behaviour is as expected (i.e. there is no bug).

Both the context A` and the context B` is in $ContextPath. Both contain a symbol n. When you input n, it is not clear whether it refers to A`n or B`n. This is determined based on the ordering of $ContextPath, and thus you may get an interpretation you didn't expect. Hence the warning.

The reason why the subsequent evaluation of the second code block doesn't trigger the warning is that it doesn't create any new symbols. Both A`n and B`n have already been created.

If you quit the kernel and evaluate the second block first, you'll get the warning again (as it creates a new symbol that causes ambiguity).


If you are writing a package, you should only place those symbols into the package context which are meant to be directly used by the package's users. Above, n is not such a symbol. It is just an implementation detail. Thus it should be created in a context that is not in $ContextPath. Conventionally, A`Private` would be used.

You should use

BeginPackage["`A`"];

f1 (* create this in A` *)

(* A symbol is created by its first "mention". This is why n was created here
   in your example. A more common way to create f1 would be
     f1::usage = "f1[] is a function";
   However, simply writing f1—and nothing else—also works, like above.
 *)

Begin["`Private`"];

f1[n_] := NotebookDirectory[n];

End[];

EndPackage[];

See Creating Mathematica packages

$\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.