Skip to main content
5 of 5
added 90 characters in body
user13892
  • 9.8k
  • 2
  • 15
  • 44

How do contexts work exactly? Is there anything special about Private` or Internal` context?

Suppose I begin a package:

BeginPackage["MyPackage`"];

Before running this command in a fresh kernel, the context and path were:

$ContextPath->$Context

{"System`", "Global`"} -> "Global`"

and afterward:

{"MyPackage`", "System`"} -> "MyPackage`"

Now if I were to declare a function Fun1:

Fun1::"usage" = "Fun1[]";

The context of Fun1 is obviously Context[Fun1]:

"MyPackage`"

Now if I begin a subcontext inside this context:

Begin["`Private`"];

Now my context and path are:

{"MyPackage`", "System`"} -> "MyPackage`Private`"

Now if I try to define a new function with the same name Fun1 here in the subcontext:

Fun1[arg_] := 1 + 1;

It gets defined in "MyPackage`" context whilst clearly the current context right now was "MyPackage`Private`".

If I were to use a different name say Fun2 here then it gets defined in the subcontext as expected:

Fun2[arg_] := 1 + 2;

Why is that? I am trying to understand the rules governing this. Does it mean if you are in a subcontext and there is a symbol with the same name existing in the outer context then the current context given by $Context is ignored if you define without using full context name?

MyPackage`Private`Fun1[arg_] := 1 + 3;

was the effect I was expecting. Is this rule general in terms of how deeply nested the current context is compared to where the symbol with the same name exists in the outer context?


I have a second question regarding BeginPackage second argument:

BeginPackage["MyPackage`",{"Package1`","Package2`"}]

is this the same as:

Needs["Package1`"];
Needs["Package2`"];
BeginPackage["MyPackage`"];

or

BeginPackage["MyPackage`"];
Needs["Package1`"];
Needs["Package2`"];

Also are there any cases where in a multipackage paclet, these can produce different results, i.e. the order in which Needs are called relative to BeginPackage matters?

Also, does these do something different?

Needs["`MyPackage`"];
BeginPackage["`MyPackage`"];
user13892
  • 9.8k
  • 2
  • 15
  • 44