Subscript and the Sorcerer's Apprentice
- To: mathgroup at smc.vnet.net
- Subject: [mg13530] Subscript and the Sorcerer's Apprentice
- From: Tom Burton <tburton at brahea.com>
- Date: Fri, 31 Jul 1998 04:33:39 -0400
- Sender: owner-wri-mathgroup at wolfram.com
The Players
The Sorcerer: Mathematica
The Apprentice: me
The Broom: Subscript
Act I
I frequently subscript symbols to mimic common mathematical notation. A
subscripted symbol x\_a in the Front End becomes the expression
Subscript[x,a] in the Kernel. Set (=) and SetDelayed (:=) assign a
definition of Subscript[x,a] to the System symbol Subscript
(System`Subscript).
Within a Module, I declare x and a to be local to the Module. Every time
I execute this Module, another definition is assigned to Subscript.
Thus, after three executions of
\!\(Module[{x, a}, x\_a = 1]\)
I might see the following three DownValues added to Subscript:
\!\({HoldPattern[x$3\_a$3] \[RuleDelayed] 1,
HoldPattern[x$4\_a$4] \[RuleDelayed] 1,
HoldPattern[x$5\_a$5] \[RuleDelayed] 1}\)
assuming that $ModuleNumber was 3, 4, and 5 when this module was
executed. These DownValues do not disappear when the Module goes out of
scope.
Version 3.0 provides a neat way to avoid these useless DownValues:
Utilities`Notation`Symbolize, whereby x\_a is translated not into
Subscript[x,a] but instead a single symbol (like x_a but with a fancier
underscore). Alas, I am addicted to the ability to manipulate
subscripts, and I am (true to my role!) stubborn besides, so I don't
use Symbolize much.
These useless DownValues of Subscript can accumulate quickly. From time
to time, I amuse myself with the awful response from the Kernel when
asked
??Subscript
Act II
I am running larger problems. The Kernel is awash in these useless
subscripts. From time to time, it abruptly quits, proclaiming "Out of
memory", owing, I suspect, to these subscripts. I am no longer amused.
These foul subscripts must go! The simplest step, Clear[Subscript],
would be too drastic. Instead, I execute the following function from
time to time
cleanSubscript[] :=
DownValues[Subscript] =
DeleteCases[DownValues[Subscript],
HoldPattern[L_ :> R_] /;
StringMatchQ[ToString[L], "*$*"]]
to clear out DownValues that appear to be useless. If I fail to call
this function often enough, I'm in trouble. This function is imperfect.
Interlude
I would like Act III to be more agreeable. How to avoid this mountain of
subscripts in the first place? One approach is to have each module
clean up after itself:
\!\(x\_a =. \)
Alas, this solution is tedious when there many subscripted symbols, and
I am (again, true to my role) lazy. So I don't do this much.
Another approach is ask Mathematica to assign the definition to the
local variable x. Neither of the following Modules leaves subscripts
behind.
\!\(Module[{x, a}, x /: x\_a = 1]\) \!\(Module[{x, a}, x\_a ^=
1]\)
Alas, this approach often unavailable, because x and a are too far
"Down":
In[26]:=
\!\(x /: x\_a[1] = 2\)
TagSet::tagpos:
Tag x in x [1] is too deep for an assigned rule to be
a
found.
The same error occurs when assigning a list or matrix of subscripted
symbols.
Set and SetDelayed assign such definitions to Subscript, but not as any
kind of Value that I recognize. They show up in response to ??:
??Subscript
System`Subscript
InputForm[Subscript[x, a][1] = 2]
but I cannot interact with this output.
Would anyone out there care to write me a happy Act III?
Thanks!