86

Link to the code on GitHub I have been using this. It's mostly Leonid's code from the stackoverflow question you linked to, but it uses Definition instead of DownValues. Symbol names are printed without any context, but the full symbol name is put into a Tooltip so you can always find out what context a symbol is in. Update FullDefinition[symbol] claims ...


75

In version 10.1, I've built something like Spelunk into GeneralUtilities`. To use it, run Needs["GeneralUtilities`"] PrintDefinitions[symbol]; This will pop up a window that shows all definitions of symbol. Here is a short summary of features: The window shows code cells containing all DownValues, OwnValues, UpValues, SubValues, and Attributes of a ...


45

This behaviour has changed since that book was published. I am writing this additional answer to make it clear how Mathematica 9 searches contexts for symbols and that even the current version 9 documentation is incorrect in describing this. How symbol lookup actually works When you enter a symbol name such as x, Mathematica will check if a symbol with ...


38

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, ...


37

Symbols are created in the current context during parsing. This should not be a problem in normal circumstances as the symbols are merely "initialized" without values or properties. See these posts for more information: Is it possible to use Begin and End inside a Manipulate? Why doesn't this use of Begin[] work? When does Mathematica create a new Symbol? ...


36

The red colouring indicates shadowing — i.e., when a symbol originally in a particular context, is exposed to the current context path, thereby clashing with another symbol of the same name in a different context, also on the context path. Example of shadowing: Here is a short example that demonstrates this. Try it out in a fresh kernel (call Quit[] ...


32

I can now offer a solution which leverages the full power of the code formatter, in its new, more robust form. Load the formatter: Import["https://raw.github.com/lshifr/CodeFormatter/master/CodeFormatter.m"] Some examples: CodeFormatterSpelunk[RunThrough] CodeFormatterSpelunk[PacletManager`CreatePaclet] In the last example, using MakeBoxes would ...


29

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


29

You should consider using the sandbox functionality. You can create a subkernel and put it in sandbox mode this way: link = LinkLaunch[First[$CommandLine]<> " -wstp -noicon"]; LinkWrite[link, Unevaluated@EvaluatePacket[Developer`StartProtectedMode[]]]; You can then interact with this subkernel using the standard LinkWrite and LinkRead functions. If ...


26

You are looking for $NewSymbol which is run every time a new symbol is created. For example, let say you only want x, y, and z as symbols, then declare them initially In[63]:= {x, y, z} (*Out[1]= {x, y, z}*) Then, set $NewSymbol to issue a message when it is used, e.g. In[2]:= $NewSymbol::undeclared = "`1` was not previously declared."; In[3]:= $NewSymbol ...


24

Since nobody has mentioned it yet... V8 introduced the undocumented flag Debug`$ExamineCode. When it is set to true, the information functions will display the definitions of ReadProtected symbols: Debug`$ExamineCode = True ??BinLists It is sometimes useful to suppress some of the internal package names to make it easier to scan the definitions. Here is ...


24

Short answer: yes, it is possible. The problem is that parsing is done line-by-line only for the top-level code. For code inside some head(s), it is first parsed as a whole. Therefore, your f is parsed to Global`f, and this is why that symbol is used. Here is what you can do, schematically: DynamicModule[{x = 5}, With[{def = MakeBoxes[f[y_] := y^2 + 1;], ...


20

Using Begin and End won't help, because .mx files are lower-level and the way they are loaded is different from normal packages. I was about to say that this isn't possible, but here is a hack which seems to work: ClearAll[loadInContext]; loadInContext[context_String,file_String/;FileExtension[file]==="mx"]:= Module[{tag}, Block[{$NewSymbol=Sow[...


18

Not an answer. Just screen shot. I booted up version 2.2 to verify the book result. And it does verify: The same result we get with version 5.2: Something changed since the book was written (screenshot from version 9 follows):


16

I would just use strings, for all their fragility: ClearAll[print]; print[sym_, {conts_String}] := With[{altptrn = Alternatives @@ Reverse[SortBy[{conts}, StringLength]]}, Print@StringReplace[ToString[InputForm@FullDefinition@sym], (x : (_ | "") ~~ altptrn ~~ y : (_ | "")) /; ! (x === "\"" && y === "\"") :> StringJoin[...


16

Your specific problem looks like you somehow managed to not load the package properly (did you evaluate Get[...]?). There's also an excess space in your long-form call to f (just before EndPackage[]) that will give you an error. Although your package will work if you fix the typo, this is not in general a good way to define your function. To see why, try: &...


16

Here I offer the safe version of Get that can be used successively to collect all the source files and contexts of packages without polluting the memory (too much). What it does I have practically reverse-engineered all the necessary functions (Get, Needs, BeginPackage, Begin, EndPackage and End) so that I could inject the monitoring code for introspection....


16

I will make no attempt to defend the fact that Mathematica simulates scoping by means of variable renaming. However, the behaviour that we see is consistent with the principles under which Mathematica does operate. Whenever Mathematica tries to interpret a symbol name, it first checks to see whether a symbol with that name already exists in a package in ...


16

I have been solving exactly the same problem about 2 years ago (http://community.wolfram.com/groups/-/m/t/125587?p_p_auth=aZGMz5bs). Students are uploading piece of Mathematica (Wolfram Language) code which is run by a testing script (in Mathematica) and the results are compared with a reference solution. To prevent the students to run potentially dangerous ...


16

code = " BeginPackage[\"Foo`\"] MyFoo::usage = \"MyFoo[] is a function\"; Begin[\"`Private`\"] foo[] := 3 (* helper function *) MyFoo[] := foo[]^2 (* my function *) bar[]:=DynamicModule[{x},{Dynamic[x],x}]; End[] EndPackage[] " Added a line with DynamicModule to show obstacles. Printing with full names: As Boxes We can use FullForm ...


15

It appears since version 3 shadowed variables are given priority, as demonstrated below. In the temp` context x is taken as temp`x unless Global`x exists. Remove[temp`x, Global`x] temp`x = 6; Begin["temp`"]; {x, Global`x} End[]; {6, x} Remove[temp`x, Global`x] temp`x = 6; x = 5; Begin["temp`"]; {x, Global`x} End[]; {5, 5}


15

The definitions aren't being lost, they're being shadowed, as described in the tutorial on contexts. Mathematica doesn't warn you about this because it only warns when there is shadowing between contexts that are listed in the $ContextPath. Since Begin only changes $Context and not $ContextPath, you don't get a warning when the symbol that causes shadowing ...


14

I've certainly encountered this behavior before. While I can't speak authoritatively, I'd think this is as designed, although it does introduce certain inconsistency. I also think that this issue is a result of clash of cultures: the end user - oriented one from the earlier days of Mathematica, and the one coming from standard software-engineering practices. ...


14

Edit: method extended for multiple contexts and unlocking mehtod added. Let's protect whatever is a new symbol. In old answer I've manually excluded symbols matching name$digits but that wasn't necessary as according to $NewSymbol details: $NewSymbol is not applied to symbols automatically created by scoping constructs such as Module. BeginPackage["...


14

If you just want backwards compatibility, there is no need to create any symbols in the System context. It seems like a bad idea to do such things. A package should create symbols only within its own context to avoid conflicts. Imagine what would happen if two different packages tried to define System`Echo, each in their own and incompatible way? I ...


13

I am not sure these are the best ways but they should work. You could do what you did with Dimensions for all the symbols in Combinatorica` For example, running this replaceAndLoad[context_String -> toContext_String] := Block[{$ContextPath}, Needs[context]; Scan[ToExpression[ toContext <> StringReplace[#, context ~~ sym__ :> sym] <...


13

General First of all, let me say that the mutual dependency of this type is usually a sign of sub-optimal design - if your two functions need to access each other, then it may mean that they should actually belong to the same package. However, in some rare cases such design can indeed simplify things. What you observed can be understood by looking at the ...


13

When you use DumpSave, it stores the expression in Notebook$xyz`thedata where the $xyz part is a unique context for that notebook. When you load the file using Get, it restores the expression to the variable in that context. However, there is no guarantee that your notebook will have the same unique context in two different sessions. Your new thedata might ...


13

The straightforward answer is: Do not try to do this!! If it were possible, it would break things. There is a specific (and complicated) way Mathematica resolves file names, which allows the standard application structure to work. It is described in the Details section of FindFile. It does not allow for indefinite recursion into subdirectories. In ...


Only top voted, non community-wiki answers of a minimum length are eligible