Saving and Restoring a Session
******************************

If for some reason you want to stop a SM session for later resumption, and simply suspending the process, `Z', is not sufficient, (for instance the machine is going down), then the SAVE command will write a file containing all your currently defined macros, variables, and vectors, along with your current history buffer as the macro all. You will be prompted before each class of objects is saved, or you can put the answers on the command line. The file is ascii, and can be edited if you so desire. The filename defaults to sm.dmp if not specified, or to the value of save_file from your .sm file. If some bug has crawled unbeknownst to us into SM, and results in some sort of panic (such as a segmentation violation), a save file called panic.dmp is written to your temporary directory, no questions asked.

To restart, RESTORE filename will read them all back, using the same default file as for SAVE if no filename is specified, and replace the current history buffer with the value of all from the savefile. Of course, you could write a macro to preserve the current buffer (see the definition of edit_all for hints). If the file wasn't written by SAVE it is assumed to be a SM history file, one of those written when you quit SM, and each line is assumed to be a command and written to the end of the history buffer. This is generally useful when you started SM in the wrong directory. It wouldn't be hard to write a macro to use RESTORE to read a history file into a macro.

One problem with SAVE is that it saves lots of macros, including some of the system ones. Specifically, all macros are saved except those beginning with ``##''. This can be avoided with the MACRO DELETE filename command, e.g.  MACRO DELETE utils SAVE 1 1 1 MACRO READ utils. The macro sav discussed under `useful macros' will do this for you, and indeed not SAVE any macros that have been read with the load macro. This is probably the best way to use the SAVE command. In addition, sav also decides to save variables and macros, only prompting you about saving vectors. sav is a good candidate for overloading (as save), and indeed is one of the macros redefined by the set_overload command.

Vectors and Arithmetic
**********************

The basic unit of data in SM is the vector, a named set of one or more numbers or strings.  There is no limit to the number of vectors that may be defined.  SM allows the user to read vectors from files or define them from the keyboard, to plot them and to perform arithmetic operations upon them. SM's string-valued vectors are less generally useful, but can be used for such purposes as labelling points on a graph.

To read a vector vec from a column of numbers in a file, where the filename has been specified using DATA and, possibly, the range of lines in the file to be used has been specified using the LINES command, use READ vec nn where nn is the column number, or READ { vec1 n1 vec2 n2 ... } to read many vectors. It is also possible to read a row, using READ ROW vec nn, where nn is the row number in the file. See READ for how to read a string-valued vector.

Instead of using simple column-oriented input it is possible to specify a format like those used by C's scanf functions (Fortran formats are not supported); if you provide your own format string you can only read numbers. For example, if your data file has lines like

     	1:12:30  -45:30:11

you could read it with read '%d:%d:%d %f:%f:%f' { hr min sec deg dmin dsec }.

A vector may also be defined as SET vec = x1,x2,dx to take on the values x1,x1+dx,...,x2, where dx defaults to 1 if omitted. If a scalar is encountered where a vector is expected, it is promoted to be a vector of the appropriate dimension; all other dimension mismatches are errors.  Example:

     SET value = 5
     SET x = 0, 50, 2
     SET y = x
     SET y = x*0 + value
     SET y[0] = 2*pi
     SET y = value
     SET x=0,1,.1 SET y=IMAGE(x,1.5)
     SET s=str
     SET s='str'
     SET s[0]=1.23
     SET x=1.23
     SET s=x
     SET s=STRING(x)

will define a scalar, value, with a value of 5, then define a vector, x, with  26 elements, valued 0, 2, 4, 6,..., 50, then define another vector, y with size 26 and the same values as x, set all 26 elements of y to have the value 5, set the first element of y to be 2 pi, set y to be a vector with one element with value 5, and finally set y to be a vector with the values taken from a horizontal cross-section from 0 to 1 through the current image. Unless a vector str is defined SET s=str is an error; to make s a string-valued vector use SET s='str'. SET s[0]=1.23 makes s[0] have the value "1.23" (a string), as s is now a pre-existing string vector. An arithmetic vector x is then defined, and s is redefined as an arithmetic vector too -- you must be careful when dealing with string vectors! Finally, we explicitly convert an arithmetic vector to a string-valued one with the STRING operator. This is a somewhat contrived example, designed mainly to illustrate the convenience of the SET command. The ability to set particular elements is mostly used in macros such as smirnov2 which calculates the Kolmogorov-Smirnov statistic from a pair of vectors.

If you don't have many data points, rather than type them into a file, and use READ vec nn to define a vector, you can use the command

     SET vec = { list }

For example

     SET r = 0,10

is equivalent to

     SET r = { 0 1 2 3 4 5 6 8 9 10 }

In fact, { list } is an expression, so SET vec = 2*{1 3 1} is also legal. If the first element of a list is a word, the vector is taken to be string-valued: SET s={ William William Henry Steven } defines a 4-element string vector, or you can use a string in quotes: SET s=<'1' 2 3 4> (if you used SET s={'1' 2 3 4} the first element would be '1' rather than 1). Once a vector is defined, you can write it to a file for later study using the PRINT command.

A scalar may be an integer, a floating point number, a scalar expression, DIMEN(vector), or WORD[expr]. The last two are the dimension of a vector, and an element of the vector with expr a scalar subscript. Note that subscripts start at 0 and that [ ] not () are used to subscript variables. The expression WORD[expr] is in fact allowed even if expr is not a scalar, in which case the result is a vector with the same dimension as expr, and with the values taken from WORD in the obvious way.

Once vectors are defined, they may be combined into expressions using the operators +, -, *, /, **, CONCAT and the functions COS(), SIN(), TAN(), ACOS(), ASIN(), ATAN(), ATAN2(), ABS(), DIMEN(), INT(), LG(), EXP(), LN(), SQRT(), STRING(), STRLEN(), and SUM(). The meaning of most of these is obvious, ATAN2 is like ATAN but takes two arguments, x and y and returns an angle in the proper sector. DIMEN returns the number of elements in a vector, SUM gives the sum of all the elements, CONCAT concatenates two vectors, INT gives the integral part of a vector, STRING converts a number to a string, and STRLEN gives the length of a string (in plotting units, not just the number of characters). STRING uses the same code as the axis-labelling routines, so FORMAT can be used to modify its behaviour; whether the x- or y-axis formats is used depends on whether the label is more nearly horizontal or vertical. An example would be

     set x=3.08e16 define s (string(x)) relocate 0.5 0.5 putlabel 5 $s

The precedence and binding are as for C (or Fortran), and may be altered by using parentheses (CONCAT has a binding just below + and -). All of these operators work element by element, so

     y = 2 + sin(x)

is interpreted as

     y_i = 2 + sin(x_i)

If there is a size mismatch the operation will only be carried out up to the length of the shorter vector and a message is printed; if VERBOSE is 1 or more, the line where the error occurred will be printed too. The constant PI is predefined.

You can also use WORD([ expr [ , ... ]]) as part of an expression, where WORD is a macro taking zero or more arguments. Suppose we define a macro pow with two arguments as

     SET $0 = $1**$2

then the command

     SET y = 10 + 2*pow(1 + x,3)

is equivalent to SET y = 10 + 2*(1 + x)**3.

In addition to these arithmetic operations, there are also logical operators == (equals), != (not equals), >, >=, <, <=, && (logical and), and || (logical or). The meanings of the symbols are the same as in C, and as in C the value 0 is false while all other values are true.

String vectors may only be concatenated, added, or tested for (in)equality. Adding two string-valued vectors concatenates their elements, so

     { a b c } + { x y z }

results in the vector ax by cz.

Testing equality for string vectors seems to cause some confusion. Consider

     set str=<'a' b c d>
     if('a' == 'str') {     # test if the strings `a' and `str' are equal
     if('a' == str) {       # test if the string `a' equals the vector `str'
     if(a == str) {         # test if the vector `a' equals the vector `str'

The second of these tests will succeed, but if you then try

     if('b' == str) {       # try to see if `b' is an element of str

the test will fail as 'b' == str is the 4-element vector { 0 1 0 1 } and only its first element is used by the if test; what you want is

     if(sum('b' == str)) {  # is `b' an element of str?

There are also a number of less mathematical operations.  If you have an IMAGE (see Image) defined, you can extract a set of values using the expression IMAGE(expr,expr), where the two exprs give the coordinates where the values are desired. Note that this may be used as a way of reading large data files that are stored unformatted. The expression HISTOGRAM(expr : expr)  can be used to convert a vector into a histogram. The second expression is taken to be the centres of the desired bins: bin boundaries are taken at the mean points (and points in the first expression lying on a boundary are taken to fall into the lower bin. Note the use of `:' not `,').

Vectors may be assigned to, using the syntax

     SET vec = expr

or

     SET vec[ expr ]  = expr

or

     SET vec = WORD(expr)

or

     SET DIMEN(vec) = number

or

     SET vec = expr1 IF(expr2)

or

     SET  vec = expr1 ? expr2 : expr3

The first form sets vec to have the value expr, element by element, vec is the name of the new vector. The form vec[expr] may be used to assign to an element of a vector, as usual the index starts at 0. Before you can use SET to assign values to the elements of a vector, you must create it using one of the other forms of the SET command.

If you want to define a vector to which you will subsequently assign values using SET vec[ expr ] = expr, you may use SET DIMEN(vec) = number which declares vec to be a vector of size number, and initialises it to zero. You can optionally supply a qualifier to the number, either a .f (the default), or a .s to specify that the vector is string valued.

If the IF clause is present, only those elements of expr1 for which the corresponding element of expr2 is true (non-zero) are copied into vec; in general vec will have a smaller dimension than expr1. The last SET statement (with ?:) again borrows from C. If expr1_i is true, then vec_i is set to expr2_i, otherwise it is set to expr3_i.  In this form of conditional assignment, the dimension of vec is the same as that of the right hand side. It may look strange, but it can be just what you want.

Each vector also has a help field, which may be used to provide a string describing the vector. The field is set by

     SET HELP vec str

and viewed by

     HELP vec

or via the string-valued expression HELP(name).

If VERBOSE is one or more, if a vector is arithmetic or string will also be noted. Vectors may be printed using the

     PRINT [ file ] [format] { vec1, ..., vecn }

command, where if the optional file is missing, the values are typed to the keyboard; if the optional format is omitted, a suitable one will be chosen for you. Any combination of string- and arithmetic-vectors may be printed. If a value exceeds 1e36, it is printed as a *. This is consistent with the convention used in reading data that a `missing' number is represented as 1.001e36; see READ for details. Vectors may be deleted with the command

     DELETE vec

and listed with the command

     LIST SET

Vectors are listed in ascii order along with their dimension, and any help string specified using the SET HELP command

Once you start writing (or using) complicated macros you'll get bitten by the fact that a macro called by a macro called by a friend's macro uses a scratch vector called x or i, and that this vector quietly overwrites your vector called x or i. To avoid this, conscientious macro writers make their vectors LOCAL. (well, to be honest the LOCAL command's a recent addition to SM so there are lots of macros out there that don't do this). After the command SET x LOCAL in a macro, any redefinitions of x within that macro, or any macros called by it, will be discarded when the macro exits. The vector isn't strictly speaking local to the macro as it's visible from macros that are more deeply nested, but the effect is similar. A word on caution: a macro can exit sooner than you expect; the classic example is

     cube     11      # print a vector's cube for people we like
                      define name local  define name :
                      if('$name' != 'Thatcher') {
                             set x local  set x = $1
                             set x = x*x*x
                             print The answer is $(x)
                      }

Because the if might be followed by an else, the macro is read and popped from the input stack before it's executed, causing confusion.

An IF clause has been added to the plotting commands, to allow only those elements of a vector which satisfy some condition to be plotted, for example

     POINTS x y IF(z > 3*x)

Of course, you could have used the IF command and the regular POINTS command if you had preferred. In fact,

     CONNECT x y IF(z > 3*x)

isn't quite the same as

     SET log = z > 3*x SET x = x IF(log)  SET y = y IF(log)
     CONNECT x y

as the former will only connect contiguous points.

Drawing Labels and SM's TeX Emulation
*************************************

There are two separate ways to specify special characters to SM, by using a syntax very similar to TeX (the type-setting system created by Donald Knuth that we used for this manual), or the traditional Mongo way. You might ask what are the advantages of TeX? One is that sub- and super- scripts are handled much more naturally, making it much harder to type M_{V = -8} when you meant M_V = -8. Another is that you no longer have to remember that theta is hidden in the Greek font as `q', you can simply type \theta. A third would be that you may well know TeX already.

If you want to make SM understand TeX strings you should define the variable TeX_strings (if you put a line TeX_strings 1 in your .sm file this will be done automatically). You can, of course, undefine it at any time to revert to the old-fashioned strings described below. Using TeX-style strings is strongly recommended by the authors; all future and most recent improvements to SM's labels are only supported in TeX mode.

If you want to change the default font used for labels, define the variable default_font; if you wanted to use the \oe (Old English) font you could either say (DEFINE default_font oe) interactively, or put a line in your .sm file: default_font oe. This affects axis as well as regular labels and only works if you use TeX_strings (of course).

For some devices with hardware fonts (for example, postscript printers or a Tektronix 4010 terminal), if expand is exactly 1, and angle is exactly 0, the hard fonts will be used for speed. Various strategies to defeat this are discussed below.

An Introduction to TeX
======================

If you don't know TeX let's start with an example:

     label \pi^{\-21/2} = {\3\int}e^{-x^2}\,dx

will print a well-known result (You'll have to RELOCATE somewhere where the label will be visible first, of course). (If you want to try it now, you should be careful typing those ^'s, as they are special to the history editor, dealing with this is discussed below.) In this example the characters \, {, }, and ^ are special (and so is _ which wasn't used). Postponing \ for the moment, ^ means `make the next group a superscript', _ means `make the next group a subscript', where a group is either a single character, a single control sequence (wait a moment!), or a string enclosed in braces. So A_a^{SM}B would appear as A_a^{SM}B (which loses something in an info file...). A \ can serve one of two functions, either turning off the special meaning of the next character (so \_ is simply a _ with no special significance), or to introduce a named `control sequence'. These fall into three groups, those that change fonts, those that serve as abbreviations for single characters (e.g. \pi in the example), and those that are macros. The font changes persist until the end of the string, or the current group, whichever comes first.

Available Fonts
===============

The available fonts are `greek', `old english', `private', `roman', `script', and `tiny'. They may be referred to either by a two-character control sequences (\gr, \oe, \pr, \rm, \sc, or \ti) or simply by the first character (e.g. \r for the roman font). In addition \i or \it can be used to make the current font italic (remember to use italics within {} so that their effect is limited!). The `bold' font \b or \bf is makes the current font bold, and can be toggled off with a second \bf if you didn't simply group it. I'd strongly recommend treating \bf like any other font change, and group them rather than relying on this toggling action.

The slant of \it letters can be controlled by the command sequence \slant, which takes an argument which is the tangent of the desired slope (i.e. it is the degree of shear). You can also compress all letters along the direction that they are being written using \condense; for example {\slant0.4\condense0.5 Hello World}.

You can alter the size of the letters by using an escape such as \6 which scales the current group (any font change is local to a group). \6 corresponds to multiplying the size by 1.2^6 or about 3, \-4 scales by 1/1.2^4 or 0.48. This is similar to the `magstep' used in scaling fonts in TeX. These scale factors are in addition to the expansion produced by going up or down (^ or _), or setting EXPAND.

SM's TeX Control Sequences
==========================

Other control sequences either consist of one non-alphabetic character, or else a name consisting only of letters, so \, or \palmtree is valid but \one2three is not. If a alphabetic name is followed by a space, the space is treated as simply delimiting the name and is discarded. For example, AB^{\alpha_\beta CD} will appear as AB^{alpha_betaCD} (note that the space after beta disappeared). How do you make just a few characters italic (script, old english, etc.)? Try ABC{\it DEF}GHI. You can't read a subscript, and want it in `tiny' font? Try \Lambda_{\ti ab}. All of the Greek letters are defined, as \alpha-\omega,\Alpha-\Omega, there are various mathematical symbols (e.g. \int, \infty, or \sqrt), some astronomical (e.g. \AA for an Angstrom symbol),

and some miscellaneous characters (e.g. \snow to draw a snowflake). You can generate a complete list of definitions by saying load fonts TeX_defs.

Some of these definitions are more complex than just special characters, if you know TeX most of them should be familiar.

\bar str
     Draw a bar over str.

\border n str
     Add an n-pixel border of whitespace to str and draw it.

\centre
\center
     Center a string horizontally

\over str1 str2
     Draw str1 over str2, separated by a horizontal line. This isn't nearly as sophisticated as TeX's \over, and never will be. It's written in SM's TeX emulator which is pretty limited. If you are a LaTeX user, SM's \frac may be more familiar.

\phantom str
     Don't actually draw str, but take up as much space as str would have if you had drawn it.

\smash str
     Draw str but pretend that it took up no space.

\strut
     Make the current formula have at least the depth and height of a parenthesis.

You can also define your own TeX definitions by using the special command \def\name{value} inside a label. It produces no output, but defines name to expand to value. For example, I could define \TeX to produce TeX by saying

     LABEL \def\TeX{T\raise-200\kern-20E\raise200X}.

Once a definition has been made it is remembered forever (well, until you leave SM actually) whatever devices you plot on. You must make sure that all curly brackets are properly paired inside your definition. You can have arguments just like real TeX, referred to as #1, #2, #3 and so forth, for example

     \def\sub#1{_{#1}}

Your SM guru can compile TeX-definitions into the binary fonts file, instructions are given in the fonts appendix.

SM's Extensions to TeX
======================

We have made a number of extensions to TeX that are useful in a plotting package, but wouldn't be especially valuable in a printed document. We have also distorted the meanings of some of TeX's control words; sorry.

\point n s
\apoint angle n s
     Insert a points (such as would be drawn with DOT) into a label. The string \point43 (or \point 4 3) will draw a point at the current position in the string, of ptype `4 3'. This sequence, from the \ to the 3, is treated as a single character as regards things like subscripts. If you want to specify an angle, use something like \apoint 45 4 0.

\hrule width
     Draw a horizontal line at the level of the current baseline, of length width in screen units. It will be multiplied by the current expansion.

\kern dx
     \kern # moves the current plot position by # horizontally, where the distance # is specified in screen units (the whole screen is 32768 across). It is multiplied by the expansion currently in effect, and may be positive or negative. See also \raise.

\line type length
     \line inserts a line into a label, at about the level of the middle of a lower-case character. e.g. \line 1 1000 will draw a line of length 1000 (in screen units, so the screen is 32768 across), of ltype 1. See also \hrule.

\move dx dy
     Move a group by (dx,dy), but don't disturb SM's current idea of where it is. This means that we can draw a line over a character with a string such as \move 0 300{\line 0 400}A. It is possible to use the commands such as \width to take the guesswork out of such commands, for example the definition of \bar is

          \def\bar#1{\move0\advance\height{#1}by100{\rule\width{#1}}#1}

\raise dy
     \raise # moves the current plot position by # vertically, where the distance # is specified in screen units (the whole screen is 32768 across). It is multiplied by the expansion currently in effect, and may be positive or negative. See also \kern.

\vrule depth height
     Draw a vertical line at the current position of depth d and height h (and width 0) in screen units. Dimensions are multiplied by the current expansion.

There are also a number of control sequences that can be used whenever a number is expected (by \kern, \line, \move, or \raise); for an example of their use see \move in the preceding table.

\advance num1 [ by ] num
     Increment first number (which can be of the form \width{...}) by the second. The by is optional.

\depth{...}
     The depth a group would have if it were drawn.

\divide num1 [ by ] num2
     Divide the num1 by num2/1000. As for \advance, num1 and num2 need not be `simple' numbers but can be combinations of widths, advances, and so on. The by is optional.

\height{...}
     The height a group would have if it were drawn.

\multiply num1 [ by ] num2
     Multiply the num1 by num2/1000. See \divide for the lack of restrictions on num1 and num2. The by is optional.

\width{...}
     The width a group would have if it were drawn

If you want to know the dimensions of the string that you have just drawn (or just not drawn, q.v. PUTLABEL 0) you can look at the internal variables $sdepth,  $sheight, and  $slength.

Caveats and Cautions when using TeX
===================================

Now for a few caveats: Firstly, because \n is a newline, you must type \\nu or "\nu" to get a nu. Secondly, the superscript character ^ is special to the history editor, so to type it interactively you must quote it with the quote_next key (usually Q or ESC-q, i.e. type Q^). Alternatively, you could change your history character to some under-used character such as % or ' (which is the solution that I use: you can choose a new character such as ' by simply putting a line history_char ' in your .sm file). Thirdly, TeX (and our pseudoTeX) are rather verbose and labels may not fit on one line. The solution is to continue the line by ending it with a \. This is probably best done within a macro, as the continuation line won't appear on your history list if typed at the prompt. You can currently have about 25 continuation lines (2000 characters).

A final point will only worry TeXies, namely that the emulation isn't perfect: for example \sum_i won't put the i beneath the summation symbol. Some of the other discrepancies were listed in the previous section.

How to Stop the Device using its Fonts
======================================

If EXPAND is set to exactly 1, and ANGLE is exactly 0, then SM will use hardware fonts, when available, in writing labels. This is faster, but can lead to two styles of labels in one plot which is ugly.

There are various ways to trick SM into always using its own fonts: you can say say ``ANGLE 360'', or use a \0 to select a font with (explicitly) no expansion. To affect the axis tick labels too, using the AXIS or BOX commands, you'll have to say ``EXPAND 1.0001'' or somesuch.

Rather than always expanding your plots, you could ask your SM Guru to edit the graphcap file to prevent a given device (usually a printer) from ever using hardware fonts. Tell her to see Graphcap. If she won't oblige, you can define your own device in your own graphcap file, and put yours first in the .sm file. For example, my .sm file includes the line

     +graphcap    /d/rhl/graphcap

and the file /d/rhl/graphcap looks like:

     # Private overrides for RHL:
     #
     postscript|postscript + no hardware fonts:\
             :TB@:TE@:TC=postscript:

Then I set $printer to postscript (also in .sm) and all is well.

An alternative is to specify the device as

             DEVICE postscript :TB@:TE@:tc=postscript:

which is perhaps simpler (you'd just define your value of printer properly).

Old-style Labels
================

If you insist on using old-style labels (which are still the default), here's a quick summary. Type \a or \\a to change to font a for one character (first form) or permanently (second form). The possible fonts are g, o, p, r, s, and t for `greek', `old english', `private', `roman', `script', and `tiny' respectively. In addition, the pseudo-fonts u and d move text `up' and `down' respectively, and i produces `italic' (actually just slanted) characters. Size changes are just like any other font change, so \6 and \-4 will affect one character and the rest of the string respectively. This is really somewhat simpler than it sounds - try

     label \gp\u\-21/2\2\d = \3\g:e\u-x\u2\d\s dx

Note that `tiny' is a misnomer, it is (nowadays) just a font that look better if you need small letters ( \t\-6 will produce a shrunken `tiny' font, just like the old days). Spaces are treated differently in different fonts, as a greek space is a negative space (i.e. a backspace), and a script space is only half as wide as a normal space.

Getting Hardcopies of Plots
***************************

There isn't really any need for this section because SM doesn't distinguish between hardcopy devices such as laser printers and other devices such as graphics terminals, except that it saves up plotting commands for hardcopy devices and sends them all when you are finished. There are, however, hard and easy ways to do anything and this section is intended to make your life a little simpler.

When a device that can produce hardcopy is closed the plot is sent off to the printer (using the command given as SY in the device's graphcap entry). The only way to close a device is to open another, any other, so it is just as good to say dev x11 as it is to say hardcopy dev x11 as the macro hardcopy does no more than open the null device. So one way to produce a plot is to say

                     device postscript
                     plotting commands
                     device x11

There are many different printers available, and even if you are using a postscript printer you might want portrait (postport) or landscape (postland) plots, so it is traditional to put the name of the desired printer into a variable printer. It is so traditional, indeed, that it can be done with a line such as

     printer     postport

in your .sm file.

The two commonest incantations are probably

                     device $printer
                     playback
                     device x11

or

                     device $printer
                     my_macro
                     device x11

which can be simplified to hcopy and hmacro my_macro respectively. The former can be given a single history number (e.g. hcopy 12) to only make a hardcopy of the one command, or a range of numbers (hcopy 1 12) to plot those lines (inclusive). The latter, if you omit the name of the macro, will prompt you to create a temporary macro that is then printed. If you want to make a hardcopy of the last line you have a choice, either hcopy -1 or hmacro, and then use the history editor to retrieve the desired line.

Some sites have many hardcopy devices of the same type, in which case they usually set up the SY command to expect an argument which is the name of the desired printer. You can deal with this by including it in your printer variable: define printer "postscript latypus" but this can be a nuisance, especially as unix already has a special (environment) variable PRINTER that specifies your default printer. The resolution is that both hcopy and hmacro are quite careful; if you have an SM variable PRINTER it is taken to be your default printer; if you don't have one they look for one in your .sm file, if they don't find one there they look for an environment (VMS: logical) variable. If all of these fail they take the first argument (hcopy) or last argument (hmacro) to be the name of the printer.

So if you have a PRINTER variable anywhere, hcopy and hmacro macro_name will work as before, if you don't then you'll have to say hcopy printer_name or hmacro macro_name printer_name.

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 Mongo), 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.