14
$\begingroup$

I have been using Mathematica for about 2 years and I'm pretty ok to write and optimize my code. Wanting to improve my practice, I often look at code examples. However, I can not determine if there is a "good way to do" with the use of functions Clear, ClearAll and other related functions (as Remove). I note that several people clear all at the beginning of each code, while other clear only the variables. So what would be a good practice?

$\endgroup$
6
  • 6
    $\begingroup$ "Clear does not clear attributes, messages, or defaults associated with symbols." - so I'd say using ClearAll should be a good habit $\endgroup$ – Kuba Apr 27 '16 at 20:17
  • 6
    $\begingroup$ Stylistically I like to at least Clear or perhaps ClearAll the name of a new function defined with SetDelayed right before its definition(s), to try and prevent lingering definitions, which are hard to debug. I typically do not bother clearing the values of symbols before simple assignments with Set, since they will be overwritten. $\endgroup$ – MarcoB Apr 27 '16 at 20:22
  • 1
    $\begingroup$ Thanks for the detailed answers. It's interesting to see the stylistic differences between the two. Following the edit of Karsten 7 which mentions the Remove function, I wonder if there are cases where this function is better. $\endgroup$ – physicien Apr 28 '16 at 17:09
  • 4
    $\begingroup$ Remove is usefull when I want to use a symbol from a package but have forgotten to load the package. Then the symbol created by the first call of the symbol (typically in the context Global) shadows the symbol in the context of the package. In this case, one must Remove the symbol. That's my unique use of Remove $\endgroup$ – andre314 Apr 30 '16 at 17:25
  • 3
    $\begingroup$ Another thing that hasn't been mentioned: blindly using Remove may create rubbish: mathematica.stackexchange.com/q/4921/1871 $\endgroup$ – xzczd Jun 2 '16 at 2:33
13
$\begingroup$

I'd like to summarize the discussion that took place in comments, since I think this is an important question, and a common source of frustration when lingering definitions cause weird behavior that can be confusing to less experienced users. Once answered (and maybe expanded), hopefully this question could be used as a target for closure as duplicate.

Stylistically I personally like to at least apply Clear or perhaps ClearAll to the name of a new function defined with SetDelayed right before its definition(s). This helps me prevent lingering definitions, which are hard to debug.

On the other hand, I typically do not bother clearing the values of symbols before simple assignments with Set (i.e. =), since any existing values (OwnValues) will be overwritten.

Notice also that, as Kuba mentioned, "Clear does not clear attributes, messages, or defaults associated with symbols.", whereas ClearAll does. (The passage is from the documentation of Clear).

Physicien then wondered about the Remove function, to which andre contributed a specific case in which Remove can be handy. If you mistakenly reference a symbol from a package before loading the package, that symbol will be created, typically in the Global`​ context, or whatever the default is in your current notebook. If you then load the package, you will run into shadowing issues, i.e. the same symbol appears in two contexts, the current one generated by your premature use, and the package one. In that case, Remove is useful to remove the superfluous symbol.

$\endgroup$
12
$\begingroup$

Actually I think "good practice" would be to try to write code which would make the use of Clear, ClearAll or Remove unnecessary. If either of them is necessary that means some of the code that was run before has left the Kernel in an undesirable state. In many cases the origin is as simple as symbols which should have been localized but were not.

The common practice to Clear or ClearAll as first statement in many answers on this site is IMO just to avoid unexpected side effects due to old definitions from previous tries to solve the problem in the question, with a high probability of having made definitions for the same symbol (names). I would not consider that to be a suggestion to start code like that in general. It rather should be seen as a result of the fact that you change the state of the Kernel with every definition you make and only if the Kernel is in a well defined state (knows the correct definitions) you can be sure your code will behave as you expect.

To Clear symbol definitions before making function definitions is mainly useful during development to wipe out the previous deficient definitions from the last try, again the goal is to guarantee a "well defined state" for your next try. If you find it to be necessary in the final "production" code that has IMHO a smell that something is wrong with the code.

As usual there are exceptions from that rule, but you really should need a Clear rarely -- in exceptional situations.

On the other hand typical use cases of Mathematica are the process of trying out and developing code, where a Clear for the next try of course makes sense. I personally prefer to frequently Quit the kernel completely which doesn't really take that long on a modern computer and then load a package file with all my current definitions. That will much more guarantee a well defined state than trying to get into such a state by Clear or ClearAll exactly those symbols that are necessary for the state you strive for. Another strategy I use nowadays is to write code so that I can load the next version of my code completely into a new namespace (Context) and leave the last version in another. That way I can even run direct comparisons. But that is admittedly a rather advanced and maybe exotic approach and not something I'd suggest in general...

$\endgroup$
2
  • 3
    $\begingroup$ Albert, I understand and appreciate your point of view. However, as you mention yourself, the great value of Mathematica to the non-programmer is precisely in the fact that I can get stuff done while not having to worry too much about "good programming practices" and "production code". As a practicing chemist, I have been using Mathematica for some time now, but never built a package: my "coding" often has to do with loose notebooks and one-offs. That's the perspective I tried to expose in my summary answer. I'm glad that you contributed an alternative point of view. $\endgroup$ – MarcoB Jun 2 '16 at 5:06
  • 1
    $\begingroup$ I absolutely know that my perspective only covers some probably not so common use cases of mathematica. But as the OP has asked explicitly for good practices I couldn't resist to at least give that point of view. I think this is a great example why it is valuable that there can be more than one answer to a question. I would also suggest that the OP should keep yours as the accepted answer as it has more practical value for most users. I hope with the additional information in mine some of them will recognize anti-patterns in their usage of that functionality... $\endgroup$ – Albert Retey Jun 2 '16 at 14:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.