Sunday, May 31, 2015

Use Contexts (Namespaces) in Mathematica to Organize Symbols and Prevent Collisions

Context is the Mathematica term for the programming device, namespace, which serves to isolate and organize related groups of Symbols and protect Symbols having the same name from conflict. Context paths and names, like file paths and names, are Strings.

Context[]//FullForm

"Global`”

You do not need to declare a Context before entering one. As usual with Symbols, Mathematica cuts out the extra and superfluous declaration step.

Contexts[] and $Context give the same result but have two different purposes. Contexts[] is used to tell the current Context[] and that of a Symbol (Context@aSymbol), while $Context is the environment variable where the current Context is stored. Always use Begin, BeginPackage, End, and EndPackage to  change Context and $Context; do not change $Context directly.

The backtick “`” is called a Context mark and delimits nested Contexts from each other, just like backslashes delimit directory hierarchies in Windows, forward slashes in web URLs and Unix, periods in domain names, colons in Macintosh directories, and in general various characters separating records and fields in data formats. All Contexts and Package names must end with a Context mark :

“MyPackage`SubPackage`”

But as in some hierarchy systems omitting the initial Context mark indicates a Context at the highest level, like the Global` or System` Contexts, while a Context mark preceding a Context name indicates a sub-Context of the current Context.

While it's rarely done, we can access any Symbol in any Context by using its full Context path name. I suspect Mathematica always sees full Symbol path names, thereby seeing all Symbols in all Contexts, and resolving apparent conflicts between identical 'nicknames' — the final Context path element only — that we may see. The following command will return the value, not of any Global value x, or the value of a Symbol x in any other Context, but the value of x in the Context TestPackage`Private`. Note this usage does not specify the Context path as a String.

TestPackage`Private`x

To change Contexts use Begin@”NewContext`” (again, preceding the Context name with a backtick Context mark if you want to make NewContext` a sub-Context of the current one).

Begin@”NewContext`”

"NewContext`"

Changing Contexts creates a push-down stack listing them. To leave NewContext`, use End[] (no Context name is necessary) and the current Context pops off the top of the stack and you re-enter the Context you were in before NewContext`. On leaving a Context Mathematica tells you what Context you were in, not which one you’re entering. To see what Context you’re in, use Context[].

End[]

NewContext`

Context[]

Global`

Just as $Path shows the sequence of directories searched by Mathematica for files, $Context shows the sequence of Contexts searched by Mathematica for symbols.

$ContextPath

{"TestPackage`", "TemplatingLoader`", "PacletManager`", "Global`", "System`"}

Mathematica attempts to order Contexts in $Path so that smaller Contexts with more specific commands, such as user-created ones, are searched before larger Contexts with more general commands, such as the ~5000 built-in commands in System` and Packages auto-loaded by Mathematica.

In a composition of commands, Mathematica uses $Context before it is changed by a command within a line. Therefore always put Begin and BeginPackage on their own line.

No comments:

Post a Comment