CleanSlate Tests and Demonstration

For detailed information about how to use the CleanSlate.m package, and the workings of the code itself, see the separate documentation file. This notebook is intended to exercise the various capabilities, error messages, etc. 

Todd Gayley
tgayley@wri.com
May 1993

The Basic Functionality

A Demonstration

$Version

First, define a variable in the Global` context before CleanSlate.m is read in. None of the CleanSlate functions should ever affect this variable or its value.

preCleanSlate = 1;

Also, read in a package before CleanSlate.m. This package context should also never be affected by any CleanSlate functions.

<<Graphics`PlotField`

Now, read in CleanSlate.m:

<<CleanSlate.m

For reference, look at the two important context-related system lists:

$ContextPath

Note that Graphics`PlotField` has imported Utilities`FilterOptions` and Geometry`Rotations`. Nothing on $ContextPath, except Global`, should ever be affected by CleanSlate.

$Packages

Note how much memory is in use for later comparison:

MemoryInUse[]

Now define some useful test variables.

global = 2;

`sub`subglobal = 3;

lateral`var = 4;

When CleanSlate purges a context (like Global`), it also purges all subcontexts (and subsubcontexts, etc.) of that context. Thus, when CleanSlate purges Global`, it will also take out the subglobal variable because it is in the context sub`, which is a subcontext of Global` (by the way the variable name is written, beginning with a `). On the other hand, var is in the context lateral`, which is not a subcontext of Global`. Since the lateral` context is not on $ContextPath, var will never be touched by CleanSlate.

Now read in a package, one that overloads some System` symbols (most packages do not do this, though).

<<Algebra`SymbolicSum`

MemoryInUse[]

About 750 Kb has been consumed by Algebra`SymbolicSum`. Actually, this package does not occupy the entire 750 Kb. It has triggered the reading in of the context System`ComplexExpand`Private`, which occupies some memory as well. There is nothing that CleanSlate can do to free this memory, or any memory occupied by stuff that gets put into the System` context or a subcontext.

The package Algebra`SymbolicSum` has added rules for several system symbols. To do this, it needed to Unprotect the symbols, and CleanSlate's modified Unprotect function has intercepted this action. The information is stored in a variable called CleanSlate`Private`alteredSystemSymbols. This is a private variable, and a user will never look at it or know about it, but it is interesting here to see its value:

CleanSlate`Private`alteredSystemSymbols

We see that Sum, among other symbols, has been modified. Here are the added rules:

ClearAttributes[Sum,ReadProtected];
??Sum

To make things more complicated, let's add a rule for Sum from the Global` context:

Unprotect[Sum];
Sum[x_] := "global rule"

Now, let's purge Algebra`SymbolicSum` only:

CleanSlate["Algebra`SymbolicSum`"]

Note that 516 Kb was freed (the other 240 Kb that disappeared when Algebra`SymbolicSum` was read in is tied up in the code for System`ComplexExpand`Private`.

Check out Sum:

??Sum

The global rule for Sum survived, and everything added in Algebra`SymbolicSum` has been purged. Further, let's check on the various other variables we defined earlier.

{preCleanSlate, global, `sub`subglobal, lateral`var}

As expected, all are still present. Only Algebra`SymbolicSum` has been removed from $ContextPath (which is the return value from the CleanSlate command above).

Now, purge everything that's purgeable:

CleanSlate[]

The Global` context was the only thing left that could be purged. Again, take a look at our user symbols:

{preCleanSlate, global, `sub`subglobal, lateral`var}

As expected, global and `sub`subglobal are the only things that were purged. Recall, preCleanSlate was present when CleanSlate.m was read in, and lateral`var was left alone because its context (lateral`) is not on $ContextPath.

UpValues, DownValues, FormatValues, and SubValues

When it removes added rules for system symbols (i.e., symbols in the System` context), CleanSlate only clears those that are among the UpValues, DownValues, FormatValues, and SubValues. This set of types of values will probably cover almost all cases, but there are some modifications that packages can make to system symbols that will not be removed by CleanSlate. Here is a somewhat fanciful example.

Unprotect[Log];

Log[a_  b_] := Log[a] + Log[b]                  (*  a downvalue of Log *)

Log /: Log[a_] - Log[b_] := Log[a/b]         (*   an upvalue of Log *)

Log[a_][b_] := Log[a] Log[b]                     (*  a subvalue of Log *)

Format[Log[a_]] := ln[a]                         (*  a formatvalue of Log*)

Options[Log] = {Broken -> True};             (*  an option of Log *)

??Log

CleanSlate[]

??Log

Note that the Option modification has not been cleared. (But the Broken symbol has been Removed....)

Error-handling
(Try to break it)

Try to purge a context that was initally on $ContextPath

CleanSlate["Graphics`PlotField`"]

Try to purge the CleanSlate` and/or System` contexts

CleanSlate["CleanSlate`"]

CleanSlate["System`"]

Try to purge a context that does not exist, or is misspelled

CleanSlate["Junk`"]

Try to purge a context that is not correctly specified (not a string ending in `)

CleanSlate[Junk]

Try to execute CleanSlate from within a package

BeginPackage["Test`", "CleanSlate`"];
CleanSlate[]
EndPackage[]

The Verbose option

Options[CleanSlate]

The Verbose->False option suppresses the printout:

CleanSlate["Global`", Verbose->False]

SetOptions[CleanSlate, Verbose->False];
CleanSlate["Global`"]

SetOptions[CleanSlate, Verbose->True];

Supplying a bogus option triggers an error message, but does not abort:

CleanSlate[Verbosse -> False]

Similarly, specifying an incorrect value for the Verbose option triggers an error, but no abort:

CleanSlate[Verbose -> Automatic]

Things that CleanSlate cannot do

Rules for System` symbols must have named variables on the left-hand side

CleanSlate cannot remove added rules for system symbols unless there is a user-defined symbol on the left-hand side of the rule. In the example below, there is none:

Unprotect[Power];
Power[__] := "a silly rule"

x^2

CleanSlate[]

x^2

The solution to this problem is to make sure there is always a named symbol on the left-hand side, even if its value is not used on the right-hand side:

Unprotect[Power];
Clear[Power]
Power[x__] := "a silly rule"

x^2

CleanSlate[]

x^2

Note that we unprotected Power again above before adding the second rule, even though it was left uprotected from the last step. This is necessary because when CleanSlate runs, it clears its list of modified system symbols. Unless we unprotect Power again, CleanSlate will not know that it is being further modified.

Locked symbols cannot be cleared

Don't set the Locked attribute on a symbol if you want to use CleanSlate on its context. It is very unlikely that a user or package author would want to lock a symbol. No symbols are locked by any of the standard packages.

Fails to count the memory occupied by the most recent output

For some reason that I do not understand, CleanSlate cannot count the memory occupied by the immediately previous output in its report of memory freed. This memory is if fact freed, it is just not reported by CleanSlate's internal call to MemoryInUse[]. This can cause confusion if CleanSlate is executed immediately after generating a large object, for example a 3D plot. Here is an example of this effect.

MemoryInUse[]

Plot3D[Sin[x y], {x,0,Pi}, {y,0,Pi}, PlotPoints->50, DisplayFunction->Identity]

The above plot occupies about 70 Kb. The DisplayFunction->Identity prevents it from being displayed, but has no effect on the kernel memory required to hold the Graphics object. We could see the 70 Kb missing if we did MemoryInUse[] at this point, but that would interfere with the demonstration, which requires that CleanSlate[] be run immediately after the plot command.

CleanSlate[]

MemoryInUse[]

Thus, CleanSlate reports no memory freed, but it has in fact freed the memory occupied by the plot.