# Scoping all symbols

After working Mathematica for a couple weeks to write a larger program, beyond doing integrals, I am starting to gain an appreciation for the Wolfram Language. There are a couple issues that drive me up the wall, and I am looking for solutions.

It comes down to how mathematica scopes, causes lots of bugs. Most programming languages will not let you access a global variable from inside a function, without explicitly asking. This causes two bugs for me:

1)Sometimes I write a block of code, and realize it would be better as a procedure. Often this chunk of code will have global variables in it, because it started out global. When I stick it in a procedure, I need to ensure all the global variables are replaced with the name of an argument to a function. If I miss one, the code usually still runs, but incorrectly, wasting hours of time on long calculations. Most programming langauges would throw an error

2)I define a function, and later add or remove a parameter, the kernel will still remember the old version. If I forget to update every single instance of that function call, it will still work, but on an old version, wreaking havoc on my calcuation.

It there a Mathematica way to solve this problem? Block and Module would not do it, because you have to define all the symbols that are local. Perhaps a block, where you clear all global variables, except functions?

While would be cool is if I could toggle my scoping. For example, at that start of a program I could say EnableDraconianScoping[]. This would raise errors. Once my code it written, I could DisableDraconianScoping[] to reduce overhead that would probably show up doing this for all my functions.

This problem is one of the few reasons I have a hard considering Mathematica for serious projects.

Thanks!

• "Most programming languages will not let you access a global variable from inside a function, without explicitly asking." - what? – ciao Jul 21 '15 at 7:52
• You raise a good point. I guess we all develop our own workflows to adapt to this feature. Some combination of ClearAll, contexts, packages, fresh kernels or function definition strategy might prove effective in your development style. – image_doctor Jul 21 '15 at 8:07
• Syntax coloring helps a bit here. You can set globals to have a bright color, and scoped variables a dull color. That way, the globals become prominent within a scoping construct. – J. M. is away Jul 21 '15 at 8:16
• Welcome to the world of dynamic interactive languages programming. One replaces the flexibility of coding by more emphasis on the programmer to use their eyes much more to catch errors. In strongly static compiled languages, the compiler can catch many errors or issue warnings, but then one loses the flexibility of quick interactions and the dynamic nature of programming. The problems you describe are not new to Mathematica. Any interactive language will have such problems (Maple, Matlab, Julia, Python, Ruby, Perl, etc...) – Nasser Jul 21 '15 at 8:23
• Now, studying R I see your point, in R the variables are local in the function scope, so you don't have this problem. Unfortunately I don't think this is something solvable in MMA. – Murta Jul 26 '15 at 3:25

Trying to understand how to cope with this exact same problem as almost driven me insane with rage.

How is it possible that the whole of mathematica doesn't have a simple way of scoping routines? How can different packages and routine work if they risk trampling on each other name down to stuff like temp variables name? Ah-ha!

The question contains the answer. The way to scope your functions and prevent either leaks from and to the Global contextm, while requiring only a minimal amount of boilerplate, is to create a package. Here's a simple example.

BeginPackage["MyRoutine"]

Routine::usage = " Routine[x] Does what you want. In this examples compute a*x^k"
SetupRoutine::usage = "SetupPIA[aa,kk] sets parameter needed to execute routine"

Begin["Private"]
SetupRoutine[aa_,kk_]:= (
a = aa;
k = kk;
)
Routine[x_] := a*x^k;

End[]

EndPackage[]


Save the file with the package in your folder under routine.m and load it using << routine.m and call the functions you've defined.

a = 7;
<< routine.m
SetupRoutine[3, 3]
Routine[3]
a


Notice that the parameter a inside your package is prevented from either affecting you current context and viceversa.

In the example above I left the SetupRoutine function exposed, but you could just as easily sweep it inside your routine and pass the parameters to your routine directly.

You can probably read about how this actually work in more detail (for example here or in the documentation, but there's a couple of thing that I understood as I learnt this:

1. The sequence of BeginPackage[".."] and Begin["Private"] are what does the trick.

I have tried several variations of starting just a context (with Begin[]) and context manipulation but always ended up leaking symbols whenever their name was present in another context.

1. The func::usage=".." declarations are required.

These declarations specify what functions will be visible outside of the package once you've loaded it. You can go crazy inside the private context with any names, but these ones need not to conflict (possibly with any other package name).

EDIT:

Keep in mind that the above is just a simple example meant to illustrate what is the simplest possible way to scope a function obtaining the feature of the scope of languages like C.

I believe this to be a superior choice whenever one wants to construct a routine which:

1. Relies on a large list of definitions and parameters which are used across several definitions. This appears to be a common occurrence in scientific computing.
2. One cannot guarantee that any of the names used inside the routine won't or aren't already used somewhere else or guaranteeing it would require a great deal of unwarranted, tedious and error-prone editing. This is also common occurrence, especially when the code being turned into a routine is in fact an encapsulation of code from a notebook where the main project was being developed.

There are two alternatives to using packages:

1. Contexts

The issue with contexts is that, without some effort on controlling the context in which symbols are declared for the first time there is always a risk of either leaking variables from Global to the current context or viceversa.

Consider this:

a  = 3;
Begin["Context"]
a = 2;
End[]


Due to the way Mathematica handles context parsing I've overwritten the global variable and the scoped variable Contexta is left unspecified. A bit absurd, given that

Begin["Context"]
a = 2;
End[]
a = 3;