Go to the previous, next section.

Overloading Keywords

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.

Go to the previous, next section.