0
$\begingroup$

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`"];
$\endgroup$
5
  • $\begingroup$ How much does this topic addresses you question: mathematica.stackexchange.com/a/43629/5478? $\endgroup$
    – Kuba
    Commented Feb 6 at 17:33
  • $\begingroup$ "Now if I try to define a new function with the same name Fun1 here in the subcontext:" But you didn't define a new function. You provided new DownValues for an existing symbol, i.e. a symbol that the evaluation engine already knows about and will find to exist in MyPackage context when it looks it up. $\endgroup$
    – lericr
    Commented Feb 6 at 17:58
  • 2
    $\begingroup$ $ContextPath tells you where the evaluator will look for symbols. If you evaluate a symbol and that symbol isn't found in $ContextPath, then it will be "created" and "assigned" to the $Context. Begin changes the $Context but not the $ContextPath. BeginPackage changes both. End reset them back to what they were, and EndPackage resets them but also adds the just created context to $ContextPath. $\endgroup$
    – lericr
    Commented Feb 6 at 18:04
  • $\begingroup$ And I don't think there is anything special about Private or Internal as part of the context name. $\endgroup$
    – lericr
    Commented Feb 6 at 18:24
  • $\begingroup$ related: mathematica.stackexchange.com/questions/13958/… $\endgroup$
    – user13892
    Commented Feb 25 at 16:11

1 Answer 1

1
$\begingroup$

"BeginPackage" does 2 things. It defines a new context and it puts the new context on the ContextPath. "Begin" only defines a new context.

A new symbol is only defined if no symbol with this name is found.

Consider the following:

Remove["pack1`*"];
$ContextPath = {"System`"};

BeginPackage["pack1`"];
Print["in pack1"]
fun1[x_] = "fun1"; Print[fun1[x]];
Print["$ContextPath= ", $ContextPath];
Print["Symbols in context pack1:", Information["pack1`*"]];

Begin["`pack2`"];
Print["in pack2"];
fun1[x_] = "fun2"; Print[fun1[x]];
newVariable = 1;
Print["$ContextPath= ", $ContextPath];
Print["Symbols in context pack1`pack2:", Information["pack1`pack2`*"]];
End[]

Print["outside pack2: fun1[x]=", fun1[x]];
Print["$ContextPath= ", $ContextPath];
EndPackage[];
$ContextPath

with output:

enter image description here

As you can see, the second definition of "fun1" does not define a new symbol, it merely redefines the symbol in pack1. Only "newVAriable is defined in "pack1pack2"

$\endgroup$

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.