33
$\begingroup$

Often new users face problems with lingering definitions that, if unaware, may cause unexpected and frustrating behaviour.

There are several answers that illustrate different aspects of the solution, but not a single place that can serve as a guide where the best strategies are compared side by side.

For example, in this answer @celtschk points to the need of using

ClearAll[Evaluate[$Context <> "*"]]

instead of

ClearAll["Global`*"]

in the cases when the Notebook has a Context set to "unique to this Notebook".

This answer by @LeonidShifrin compares Remove versus ClearAll.

In this other answer @Szabolcs gives an extensive explanation to the "significant practical differences" between Quit versus ClearAll["Global`*"].

And here @C.E. points to the use of

Needs["Utilities`CleanSlate`"]
CleanSlate[];
ClearInOut[];

Ultimately the advice seems to come to actually closing the kernel and starting one fresh, either via Exit or Quit.

Quit[]

But that doesn't cover preventive measures nor the possibility of a Dynamic cell in the notebook, or initialization commands or any other mechanism that could re-spawn definitions.

Here I'm hoping for a canonical guide to the problem of a fresh kernel.

  1. Prevention
  2. New kernel
  3. Cleaning
$\endgroup$
0

5 Answers 5

10
$\begingroup$

NEW KERNEL

This is a Community Wiki answer, experienced users are welcome to add to it and correct mistakes.


To get a fresh kernel for the current notebook, one can either kill the current kernel and re-start it or associate and start a new different kernel.

Killing current kernel

Quit and Exit both terminates a Wolfram Language kernel session.

Simply

Quit[]

enter image description here

Alternately, one can select

Evaluation > Quit Kernel > Local

from the menu bar. If you have set up alternate kernels (see below), replace "Local" with that kernel's name instead.

Configure alternative local kernels

Sometimes killing the current kernel may not be desirable, and the best approach is to start a second kernel.

If you don't have a second kernel already configured, then start by configuring a new kernel:

Evaluation > Kernel configuration options > Add > OK

or

CurrentValue[
  $FrontEnd,
  {EvaluatorNames, "Local2"}
  ] = {"AutoStartOnLaunch" -> False}

Associate a new kernel to the notebook

Then, associate a different kernel to the current notebook:

Evaluation > Notebook's kernel > #kernel-name#

or

CurrentValue[
  EvaluationNotebook[], 
  Evaluator
  ] = "Local2"

Example

The animation shows the process to configure and associate a secondary local kernel.

enter image description here

$\endgroup$
10
$\begingroup$

PREVENTION

This is a Community Wiki answer, experienced users are welcome to add to it and correct mistakes.


Best practice is to avoid the need to clean the kernel at all, by avoiding the creation of lingering definitions that may later obscures the behaviour of Mathematica.

Mathematica advises :

When you write a program in the Wolfram Language, you should always try to set it up so that its parts are as independent as possible.

Some ways to avoid lingering definitions are:

  1. Avoid creating variables
  2. Use nameless pure functions
  3. Scoping, keep variables local
  4. Use ReplaceAll
  5. Use long descriptive names

1. No variables

Take full advantage of Functional Programming and nest or compose all or most of your operations.

Do

f[g[h[x]]]

Instead of

a=h[x];
b=g[a];
c=f[b];
c

2. Pure functions

You can create functions without a name, using Function or its short form (#)&. Read about Pure Functions.

Do

Map[(2 # + 1) &, Range[4]]

Instead of

f[n_] := 2 n + 1;
Map[f, Range[4]]

3. Scoping

You can limit the scope where a variable is defined using Scoping Constructs, effectively creating local variables. Look at Module, Block, With and when to use each.

With[
 {a = 3, b = 4},
 a^2 + b^2
 ]

4. ReplaceAll

If you need to evaluate your expression for a particular argument or parameter you can use ReplaceAll or its short form /.

π r^2 /. r -> 3.656365
(* 42. *)

5. Variable names

The shorter and common-place is your variable name, the most likely is to collide with something else. Don't store your data in a variable called x and then complain that Series[Sin[x], {x,0,3}] doesn't work. Use long names that start lowercase, to avoid using Symbols that have built-in meaning in Mathematica, like C, D, E, I, K, N, O.

$\endgroup$
3
  • $\begingroup$ I used to do f[g[h[x]]] quite often but I found it could make my code quite unintelligible / less obvious. I now try to make my intentions more obvious by introducing variables in each step of calculation but as addressed in this post I end up with lots of lingering variables. Are there any thoughts/guides on best practice in dealing with this tension? $\endgroup$ Commented Nov 7, 2022 at 11:31
  • $\begingroup$ @IntroductionToProbability if you feel you need the variable name for clarity, you can still use it within a Scoping Construct, like Module. Creating variables is not forbidden, you just need to be aware of the alternatives and compromises you are making by choosing one. $\endgroup$
    – rhermans
    Commented Nov 7, 2022 at 11:43
  • $\begingroup$ That's a good point. I tend to use Module often in function definitions but almost never as a pure scoping construct. I will change this in future to avoid lingering variables over large notebooks. $\endgroup$ Commented Nov 7, 2022 at 11:52
4
$\begingroup$

The following may not be so useful in packages, but in open notebook evaluation the kernel can be repeatedly quit like so, using a tip from Arnoud Buzing.

In this case the orange cells evaluate repeatedly until b reaches 4. The value of a is lost on each quit.

enter image description here

Code text

ClearEvaluationQueueOnKernelQuit /. Options[$FrontEndSession]

SetOptions[$FrontEndSession, "ClearEvaluationQueueOnKernelQuit" -> False]

Clear[a, b]

a = If[ValueQ[a], a + 1, 1];
b = If[ValueQ[b], b + 1, 1];
SetOptions[EvaluationNotebook[], TaggingRules -> {"b" -> b}]

Quit[]

b = CurrentValue[{TaggingRules, "b"}];
If[b < 4,
 SelectionMove[nb = EvaluationNotebook[], Previous, Cell, 3];
 FrontEndExecute[FrontEndToken[nb, "SelectNextLine"]];
 FrontEndExecute[FrontEndToken[nb, "SelectNextLine"]];
 SelectionEvaluate[nb],
 {a, b}]
$\endgroup$
3
$\begingroup$

Cleaning

This is a Community Wiki answer, experienced users are welcome to add to it and correct mistakes.


Most of the solutions are already listed in the question.

ClearAll

In general this should be enough

ClearAll@"`*"

Here "`*" means all the symbols in current context. You may be more familiar with

ClearAll["Global`*"]

However, in the cases when the Notebook has a Context set to "unique to this Notebook" (See here), it won't work.

Please notice a single

ClearAll

with no argument won't have any effect!

Remove

Remove should not be used for this, see 37624 and 4921 .

Quit and Exit

Just quitting or exiting the Kernel and starting a new one will remove all lingering definitions, expect for the ones that are re-defined by initialization files like init.m. This other answer discussed new Kernel in detail.

Utilities`CleanSlate`

Undocumented utility

Needs["Utilities`CleanSlate`"]
CleanSlate[];
ClearInOut[];

Caveat

But that doesn't cover preventive measures nor the possibility of a Dynamic cell in the notebook, or initialization commands or any other mechanism that could re-spawn definitions.

$\endgroup$
-4
$\begingroup$

rhermans mentioned using long descriptive variable names. Those variable names are even less likely to collide with other variables if they are a regular characters mixed with Script, Gothic and DoubleStruck characters. For example:

example

This approach is used in the source code of the Notation` package. Also keep in mind that the full name of built-in symbols always starts with a capital letter. If your variable starts with a capital letter and doesn't use Script, Gothic or DoubleStruck characters, it may be a built-in symbol in a future Mathematica release.

$\endgroup$
1
  • 1
    $\begingroup$ This is bad because it is cumbersome to write, not easy to sport differences in variable names, you cannot easily copy your code to an IDE and the e in your second variable looks like it is the exponential constant E (or [esc] ee [esc] where [esc] is the escape key $\endgroup$ Commented Nov 7, 2022 at 12:00

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.