38
$\begingroup$

This question applies to any package, but I encountered this problem while working with graphs. There are symbols in the Combinatorica package (such as Graph, IncidenceMatrix, EdgeStyle, and others) that have the same name as analogous symbols in System. If I execute Needs[Combinatorica`], then I can access Combinatorica`Graph by the name Graph, but if I want to access System`Graph, I have to write System`Graph.

I want to use the Combinatorica` prefix to access all the symbols in Combinatorica`, and I want to access System` symbols without using a prefix. And I don't want to have the symbols Graph, IncidenceMatrix, and so on, in red in Mathematica because of the naming conflict.

Is there a way to use the Combinatorica` package without introducing naming conflicts?

$\endgroup$
0

3 Answers 3

33
$\begingroup$

Shadowing occurs only when there are two functions with the same name that are in $ContextPath. So right after you do <<Combinatorica`, do the following:

$ContextPath = Rest@$ContextPath;

What this does is that it removes Combinatorica (which is the package you just loaded). Now the only Graph function that's on the path is System`Graph and you can call it simply by the name, without the prefix. To access any functions from the package, use the prefix, as Combinatorica`Graph.

If Combinatorica` was loaded a while ago and you have loaded other packages in between, Rest@... is not going to be helpful. In that case, use:

$ContextPath = DeleteCases[$ContextPath, "Combinatorica`"];
$\endgroup$
42
$\begingroup$

The answer of @R.M. already explains the essence of the problem. You can streamline the process of removing the Combinatorica from the $ContextPath by loading it via

Block[{$ContextPath},  Needs["Combinatorica`"]]

(or use Get intead of Needs, although Needs is a preferred way to load a package). In this way, you don't have to do anything afterwards, since, once the scope of Block is left, the $ContextPath automatically is reset to its previous value.

This is a generally useful trick to load packages without adding them to the $ContextPath. I found it quite useful on many occasions.

$\endgroup$
1
  • 5
    $\begingroup$ Here's something that's good to be aware of (see under P.S.) If using Combinatorica, there's a chance one might need to use the ToCombinatoricaGraph function as well. $\endgroup$
    – Szabolcs
    Commented Apr 21, 2013 at 2:34
4
$\begingroup$

One way is to use something like Graph=System`Graph; and use Graph which refers to System`Graph thereafter. You can use any other name such as g=System`Graph as well. The downside is that you have to do it for any function.

Edit: This does the trick:

rep = StringReplace[#, "System`" -> ""] &;
Scan[
 Unprotect[#]; ToExpression[# <> "=System`" <> #]; Protect[#]; &,
 Intersection[
  rep /@ Names["Combinatorica`*"],
  rep /@ Names["System`*"]
  ]
 ]
$\endgroup$
2
  • 1
    $\begingroup$ You don't have to do the rep /@ Names["Combinatorica`*"] part, you know... $\endgroup$ Commented May 15, 2012 at 3:55
  • $\begingroup$ Graph = System`Graph sounds like a very bad idea. If Graph refers to Combinatorica`Graph, doing this will break Combinatorica. Contexts/namespaces in Mathematica don't work like in Python. $\endgroup$
    – Szabolcs
    Commented Jan 2, 2018 at 12:04

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.