Sometimes you might wish that SM's authors had decided to make
a command behave a bit differently, for instance that ERASE or
QUIT didn't appear on the history list, or that SAVE deleted
all the system macros before saving your environment. Of course, you can
(usually) write macros to get around these annoyances, but you can't easily give them the same names as the original commands (for these
examples the macros are called era, q, and sav).
It is possible to change the meaning of keywords (to `overload' them),
but it can be confusing, primarily because your
new commands may not behave the same way that this manual claims.
For example, if you were perverse, you could define points
to mean QUIT. Another danger is that you could end up with a
recursive call -- for instance if you wrote your own version of box that did all sorts of cunning things, then drew a box. If you
said box in your macro, then overloaded the keyword, you'd have
a macro that called itself. If you tried to use it, nothing would
happen for a while, and then you'd start getting messages about "extending
i/o stack" until you hit ^C. Or if you redefined help to mean
DELETE HISTORY HELP (in upper case to avoid recursive calls, and
in case delete has been overloaded), then set help vec Help string
won't work (you'd have to use set HELP vec ...).
Despite these warnings, overloading the meaning of
SM's keywords can be very convenient. There are two sets of
system macros that do just this, the compatibility ones (see section Tips for Mongo Users),
and one called set_overload that is described below.
In addition to the semi-trivial use of overloading to allow you to type
erase not era, it is possible to add extra functionality
to simple commands. For example, set_overload defines window
to save the window parameters in variables, and box then uses these
values to label appropriate axes in touching boxes. Another example is that
(when overloaded) lines saves the line numbers used, so that you
can write a macro to print the top 10 lines of a file (it's called head).
So how do you do it? The command OVERLOAD keyword # will remove
the special meaning of lowercase keyword if # is
non-zero, or reinstate it otherwise. You can still use the uppercase form
-- you can't overload that. So now that e.g. box has no
special meaning you can define it to be a macro. What the set_overload macro does is to define new meanings for a number
of keywords, the new definitions are in the macro file `overload'.
If you intend using them (and I do all the time) you should look at
this file.
You can get them loaded by default by having a line overload 1 in your
`.sm' file.
If you don't like some, e.g. box, you can simply say OVERLOAD
box 0 in your private startup file (see `private initialisation')
which is run after the system startup.
Most of the changes are benign, but not all. For example, the
new definition of relocate allows expressions, but it'll break
if you try to say relocate ( 100 1000 ) to move to absolute
screen coordinates. You can still say RELOCATE ( 100 1000) of
course, and that's why most of the system macros are actually written
in uppercase. The definition of box (actually bo,
which box calls) may seem very complex, but
it has to deal with box \n as well as box 1 2, and it
must know if you have used the WINDOW command.
This brings up another point -- if you overload keywords,
you could slow SM down. It isn't that overloading is
inefficient, it's just that the macros that replace the old keywords
may do a good deal of work, box is a case in point. Even when
the macro is short and to the point, it's still extra work to parse
the original word and find its value as a macro.