%-*-EMaxima-*-
\label{prog-lang}

This chapter assumes that readers are familiar with the basic ideas of
algebraic manipulation from Chapter~\ref{primer},
and know at least one programming language, and wish to use \Max\
for more ambitious tasks than can be handled in a few sequential
commands. If you are familiar with Pascal or Algol 60, you will probably
find this adequate as a programming background. Familiarity with Fortran
or Basic is less useful.

\Max's user-programming language\footnote{The system-programming language used 
for implementing \Max\, namely LISP, is quite different. If you wish to see 
how \Max\ was constructed, you need to know LISP to understand the source code.}
is designed to allow you
to define program modules or {\it functions} for algebraic manipulation.
Each module uses zero or more arguments, and returns an
algebraic expression.  Since numbers are special cases
of algebraic expressions, \Max's user-language
can be used as a numeric language too.  Because the language
is implemented as an interpreter it is usually
more general than compiler-based languages, and also
tends to be rather slow in tight inner loops of simple operations,
by comparison.
It has novel linguistic features, some of which are illustrated below.

\section{Some Examples}

{\tt f1} and {\tt f2} defined below, are versions of the {\it factorial} 
function.   Observe the punctuation
carefully.  Assignment is {\tt :}, function definition is {\tt :=}, 
statements are separated from one another by {\tt ,} (not {\it terminated}
by commas). The label {\it loop} is set off by a comma as though it
were a statement too.  We have added indentation to make the programs
conform to what you might expect, but extra spaces and tabs are optional.
There is a conditional execution statement (the {\tt if}) which has
an optional {\tt else} clause.

\beginmaximasession
f1(x):=if x<1 then 1 else x*f1(x-1)$
f1(5);
f2(x) := block ([temp],
                temp:1,
                while x > 1 do (
                        temp:x*temp,
                        x:x-1),   /*end while*/
                temp)$
f2(5);
\maximasession
(C1) f1(x):=if x<1 then 1 else x*f1(x-1)$

(C2) f1(5);

(D2)                                  120
(C3) f2(x) := block ([temp],
                temp:1,
                while x > 1 do (
                        temp:x*temp,
                        x:x-1),   /*end while*/
                temp)$

(C4) f2(5);

(D4)                                  120
\endmaximasession

Observe the simplicity of using \Max\ compared to, say, Pascal.  There is no
need to write a {\it driver} or main program
with input or output commands.  The input is provided through
function application on an argument, and the output is the displayed value.

Every command or function in \Max\
has a value, and may, in addition, have some side-effects, such as the
setting of variables, or the printing of messages.

The {\tt block}
construction illustrated above
is analogous to a procedure declaration.
The first part of it is a list of local variables, and following
that, expressions which are evaluated in order.
Certain expressions or commands make sense only within a block, not
at 
\Max's command level:
these are labels, {\tt return}
s and {\tt go}
s. The semantics of each
of these
commands conforms to the usual intuitive meaning.  If the last statement
in a {\tt block}
does not cause a transfer of control, and {\it execution
falls through the bottom}, the value returned from the 
{\tt  block}
is the value of the last expression evaluated.

\section{Unconventional Conditionals}

The next example shows a function with a side-effect, but the major
point is to illustrate some subtleties which you may not have thought
about in
conditional statements ({\tt if-then-else}
).

If you were asked, {\it Is A greater than B}, it would seem you could respond
either {\it yes} or {\it no}. In your conventional programming language, certainly,
that would be a reasonable assumption.  But really, wouldn't it
be appropriate in some circumstances for you to answer, {\it How should I know?}?

That option is preserved in \Max.  If the flag {\tt prederror}
is set to {\tt true}, the default, and if \Max\
is unable to evaluate a predicate, it signals an error, and unless
directed otherwise, returns control to the top-level
\Max\
command monitor.
However, if the {\tt prederror}
flag is {\tt false}, execution continues
to the next statement, ignoring both 
{\tt then}
and {\tt  else}
clauses!

This is illustrated below:

\beginmaximasession
test(x,y):=block([],
        if x > y then print(x, "is greater than", y)
                 else print(x, "is not greater than", y),
        return(alldone))$
test(4,3);
test(3,4);
test(y^2+1,-y);
prederror:false$
test(y^2+1,-y);
\maximasession
(C5) test(x,y):=block([],
        if x > y then print(x, "is greater than", y)
                 else print(x, "is not greater than", y),
        return(alldone))$

(C6) test(4,3);

4 is greater than 3 
(D6)                                alldone
(C7) test(3,4);

3 is not greater than 4 
(D7)                                alldone
(C8) test(y^2+1,-y);

MACSYMA was unable to evaluate the predicate:
ERREXP1
#0: test(x=y^2+1,y=-y)
 -- an error.  Quitting.  To debug this try DEBUGMODE(TRUE);)
(C9) prederror:false$

(C10) test(y^2+1,-y);

(D10)                               alldone
\endmaximasession

Note that no message was printed for line 
{\tt d10,}
but the return value, {\it alldone}
was displayed.

\section{Assumptions}

What do YOU think? Is $y^2 + 1 > -y$ ?  For this question to make sense,
both sides of the inequality must be in the same ordered domain.  We
do not know, offhand, whether $y$ can assume values which are matrices,
complex numbers, sets, or even programs!

If $y$ were known to be real, or more specifically, positive real, a program
could try some deduction.  \Max\ has some features of this nature, as 
illustrated below.

\beginmaximasession
assume(y>0);
test(y^2+1,-y);
\maximasession
(C11) assume(y>0);

(D11)                               [y > 0]
(C12) test(y^2+1,-y);

 2
y  + 1 is greater than - y 
(D12)                               alldone
\endmaximasession

If we wish
\Max\
to forget that assumption,

\beginmaximasession
forget(y>0);
\maximasession
(C13) forget(y>0);

(D13)                               [y > 0]
\endmaximasession

\section{Arbitrary Numbers of Parameters}

Ambitious packages of programs have been written by many
\Max\
users.
Sometimes the requirement that a command has a fixed number of arguments
causes discomfort\footnote{The language Pascal does not allow you to define
a function {\tt f} which can
be used with a variable number of actual parameters, although
the Pascal design includes built-in procedures with variable numbers of
arguments ({\tt write} for example).}.
It is possible to write a \Max\ program which counts the
number of arguments it is given, sets default values for others, and
does any number of clever things. A simple example is shown below. Note
the way the {\it left-hand-side} of the {\it :=} is set up.

\beginmaximasession
prog3([l]) := block( [],
             print ("l is bound to", l, "and l[1] is" ,l[1]),
             return(length(l)))$
prog3(a,b,c,d);
prog3(a,b);
\maximasession
(C14) prog3([l]) := block( [],
             print ("l is bound to", l, "and l[1] is" ,l[1]),
             return(length(l)))$

(C15) prog3(a,b,c,d);

l is bound to [a, b, c, d] and l[1] is a 
(D15)                                  4
(C16) prog3(a,b);

l is bound to [a, b] and l[1] is a 
(D16)                                  2
\endmaximasession

\section{Arrays}

Arrays are a useful data structure, and are provided in most programming languages. 
\Max\ provides arrays, but does not require that they be declared, or that
they have numeric (integer) index-sets. 
Rather than writing a program to fill up an array and then iterating
through all elements, sometimes it is easier to describe a program
to generate elements as they are called for.  Such array-associated
functions are often quite convenient.  The usual
way you set them up is to provide specific values for certain
index values, and then let others be assigned as needed.  
Note carefully the use of {\tt :=} and {\tt :}.

\beginmaximasession
a[4]:4*u;
a[22/7]:%pi;
a[x]:mystery;
a[h]:=cos(h);
a[3];
a[x+1];
\maximasession
(C17) a[4]:4*u;

(D17)                                 4 u
(C18) a[22/7]:%pi;

(D18)                                 %PI
(C19) a[x]:mystery;

(D19)                               mystery
(C20) a[h]:=cos(h);

(D20)                            a  := COS(h)
                                  h
(C21) a[3];

(D21)                               COS(3)
(C22) a[x+1];

(D22)                             COS(x + 1)
\endmaximasession


You might wonder what the value of $a$ is, after all this.  Most
disappointing:

\beginmaximasession
a;
\maximasession
(C23) a;

(D23)                                  a
\endmaximasession

The information that you are after is available this way:

\beginmaximasession
arrayinfo(a);
\maximasession
(C24) arrayinfo(a);

                                     22
(D24)              [HASHED, 1, [3], [--], [4], [x], [x + 1]]
                                     7
\endmaximasession

The list of information supplied indicates several aspects
of the array.  It is
{\it hashed}: uses the data-structure of a hash-table for storage
(this is a common encoding trick discussed in data structure texts).
The number of subscripts is 1. The specific indexes for which it has
recorded values are listed.  The array-associated function defined
on line
{\tt c20}
can be displayed
by {\tt dispfun}.

\section{Iteration}

{\tt For} loops provide the major iteration facility in \Max.
Three examples which illustrate variants of this are the factorial
functions below:

\beginmaximasession
f3(n) := block([temp],
                temp:1,
                for i:1 thru n do temp : temp*i,
                return(temp))$
f4(n) := block([temp],
                temp:1,
                for i:n step -1 thru 1 do temp : temp*i,
                return(temp))$
f5(n) := block([temp],
                temp:1,
                for i:n unless i <= 1 do (temp : temp*i , i:i-2),
                return(temp))$
\maximasession
(C25) f3(n) := block([temp],
                temp:1,
                for i:1 thru n do temp : temp*i,
                return(temp))$

(C26) f4(n) := block([temp],
                temp:1,
                for i:n step -1 thru 1 do temp : temp*i,
                return(temp))$

(C27) f5(n) := block([temp],
                temp:1,
                for i:n unless i <= 1 do (temp : temp*i , i:i-2),
                return(temp))$

\endmaximasession

Decrementing $i$ by 2 in the previous program was needed because the default
step size of 1 is added to $i$ each time through. {\tt F5}
is certainly
a perverse program.
Incidentally, {\tt return}
s from within a {\tt for}
exit from the loop, and not from
the enclosing 
{\tt block.}
It is important to
note that one can group a collection of statement to be {\it done} together
with parentheses, as illustrated in
{\tt f5.}

\section{Serious Business}

Most serious users of
\Max\
find that they are repeatedly using the same programs, and need to
save them for another day.  Some users also find they rarely get
the programs or the data quite right the first time, and would rather
type these things in to a text editor, and have
\Max\
gobble the text up from a file rather than the keyboard.
Publication quality programs require comments and other features you
are unlikely to want to type into
\Max\
interactively.

Some people perfect a function or get an algebraic
expression correct by typing definitions and commands into a file,
say, {\tt newstuff}, using an editor such as  {\tt vi}
or {\tt emacs}
and then within
\Max\
type {\tt batch(newstuff);}.  If your file-name has funny characters
like periods or slashes, you must use quotes. For example, {\tt batch("/usr/local/maxima/demo.begin")}.

\Max\
then reads the statements the file, assigning labels etc., and if there are syntax
or other errors, prompts for help from the keyboard.  If you want it
to continue on to the next line after an error, type {\tt batcon(true);}.

Reading very large text files of programs and data can be slow using
{\tt batch}, and if
you are not changing the text, you might prefer saving your environment
in another way.
You can use {\tt save(savedstuff,all);}
to save every named or labelled
object in a
\Max\
system, on the file 
{\tt savedstuff}
in your working directory.  
(You better have write-permission or you'll get an error message.)  Another
time you can start up from where you left off by typing
{\tt loadfile(savedstuff);}
into a fresh \Max.
You can load several saved files into a single system. Naturally if the
files contain items with identical names, there is a potential for
conflict. These will be resolved in favor of the last item read in.

If you want to save only some material you have produced, say only the
functions defined and the values of variables x, y, and z, you can type 
\begin{center}
{\tt save(savfunxyz,functions,x,y,z);}
\end{center}

A neat way to save a useful section of your environment is
to (carefully) use {\tt kill}
to remove useless
items first, and
then save {\tt all}
that is left.  Doing {\tt kill(labels,...)}
after first making sure that any useful result also has a name
other than a c or d-label is sometimes a good start.  You generally
should not save every computation, since disk space is not
infinite.

\section{Hardcopy}

If you print out the files produced by {\tt save}
to show to your
colleagues who are as yet unconvinced of the merits of
\Max\,
you will be disappointed.  While such files are {\it ASCII} character
text, they do not make easy reading for persons uninitiated in various
arcane matters.

What you might want to do, then, is store human-readable versions of
your output on a file.  This is especially useful if you have a
display terminal, or a slow hardcopy printer.
\Max\
provides a way of opening a file for echoing both input and output of
the system.
The command
{\tt writefile(fn);}
where fn is a filename, starts the echoing, and
{\tt closefile();}
stops the echoing.
If you want the output to be human-readable after being run through
a typesetting program (\TeX, for example), you can experiment with
the output produced by setting {\tt typeset : true}.
(Suggestion: {\tt gcprint : false} is a good idea.)


\section{Return to Arrays and Functions}

\Max\
provides a fascinating trick: arrays of functions. Imagine an array, each
of whose elements is a function.  For example, Legendre polynomials have
an index, and an argument.  Thus we can refer to $ P_4 ( z^2 )$.
Just as arrays can
have an associated function, function-arrays can have such an associated
function.

Because we like to show off occasionally, and typesetting can be done by the 
\Max\ system, we illustrate this feature here.
This was produced by saving output in a file
and running it through \TeX{}.

\beginmaximasession
p[n](x):=ratsimp(1/(2^n*n!)*diff((x^2-1)^n,x,n));
p[4];
p[4](y+1);
\maximatexsession
\C31.  p[n](x):=ratsimp(1/(2^n*n!)*diff((x^2-1)^n,x,n)); \\
\D31.   p_{n}(x):=\mathrm{RATSIMP}\left({{1}\over{2^{n}\*n!}}\*
 \mathrm{DIFF}\left(\left(x^{2}-1\right)^{n},\linebreak[0]x
 ,\linebreak[0]n\right)\right) \\
\C32.  p[4]; \\
\D32.   \mathrm{LAMBDA}\left(\left[ x \right] ,\linebreak[0]{{35\*x^{4}
 -30\*x^{2}+3}\over{8}}\right) \\
\C33.  p[4](y+1); \\
\D33.   {{35\*\left(y+1\right)^{4}-30\*\left(y+1\right)^{2}+3}\over{8}}
  \\
\endmaximasession

The {\it lambda} ($\lambda$) notation for a raw function of one
variable appears on line {\tt c29}.  This notation comes from the 
{$\lambda$-calculus} used to describe the programming language LISP, 
and illustrates the fact that \Max\
can talk about such structures. You can generally ignore this fact, however.

\section{More Useful Examples}

As has been indicated earlier, procedures in \Max\ can be used for almost any 
classical programming purposes (e.g. numerical techniques, combinatorial 
search).
We have already indicated some differences from a purely numerical
language, such as FORTRAN.  We have seen that in \Max\ there are no required
type declarations, and floating-point numbers, while {\it contagious}
in the sense that mixed-mode (floating-point + integer) is converted
to floating-point, do not
necessarily arise from certain calculations.  For example,
{\tt sin(3)} normally results in {\tt sin(3)} in \Max\,
rather than its floating-point equivalent.
{\tt sin(3.0)} will, however, return a floating-point number.
The numerical subroutine below, a Newton's method zero-finder
sets the flag {\tt numer} to {\tt true} to force \Max\
to convert most expressions free of indeterminates to numbers.  

This program uses Newton's method to find a zero of the expression {\tt exp}
which depends on the variable {\tt var.} The iteration starts with {\tt var=x0}
and terminates when the expression, evaluated at the trial-point,
has absolute value less than {\tt eps.} The derivative of {\tt exp}
is computed algebraically, and its value is computed at various
points as the search is being conducted:

\beginmaximasession
 newton(exp,var,x0,eps):=                   /* 1 */
                block([xn,s,numer],             /* 2 */
                numer:true,                     /* 3 */
                s:diff(exp,var),                /* 4 */
                xn:x0,                          /* 5 */
          while abs(subst(xn,var,exp)) >  eps do 
                xn:xn-subst(xn,var,exp)/subst(xn,var,s),
          return(xn) )                         /* 8 */$
\maximasession
(C1) newton(exp,var,x0,eps):=                   /* 1 */
                block([xn,s,numer],             /* 2 */
                numer:true,                     /* 3 */
                s:diff(exp,var),                /* 4 */
                xn:x0,                          /* 5 */
          while abs(subst(xn,var,exp)) >  eps do 
                xn:xn-subst(xn,var,exp)/subst(xn,var,s),
          return(xn) )                         /* 8 */$

\endmaximasession

This procedure for Newton's method uses an explicit expression
for the first argument {\tt exp} (e.g. {\tt sin(x)*erf(2*x)-\%e\^x}).
It is not a function name, e.g. {\tt f}
as we used before.  The use of such an expression is straightforward and
probably the best way for a beginner.  The resulting program is
somewhat verbose, because, as illustrated in lines 6 and 7 above,
it is necessary to substitute values for variables in the expression
and its derivative, {\tt s}, to get numbers.  Note the setting of {\tt numer}
on line 3 to assure that the {\tt if} statement on line 6 would get numerical 
values for its test.  The rest of the procedure is the classical Newton 
iteration.  The advantage of this procedure 
over a purely numerical one is that it takes advantage
of the ability to compute the derivative of {\tt exp}
algebraically and automatically, once, before evaluating it at any point.

Another item to observe here is the use of comments in the text of
programs which are 
{\tt batch}
ed in to the system. {\tt  /* This is a comment */ .}

There are often many different ways of expressing the same computation,
and some of them may be substantially more convenient or efficient
than others.  While it may not make much of a difference in
efficiency in this case, the following revision of the
{\tt newton}
procedure illustrates some techniques you may find useful
in
\Max.

\beginmaximasession
newton(exp,var,x0,eps):=                   /* 1 */
block([ xn:x0, s:diff(exp,var), numer:true],    /* 2 */
        define(f(var), exp),                    /* 3 */
        define(fprime(var),s),                  /* 4 */
  loop, if abs(f(xn)) < eps then return(xn),    /* 5 */
        xn: xn - f(xn)/fprime(xn),              /* 6 */
        go (loop) )                             /* 7 */ $
\maximasession
(C2) newton(exp,var,x0,eps):=                   /* 1 */
block([ xn:x0, s:diff(exp,var), numer:true],    /* 2 */
        define(f(var), exp),                    /* 3 */
        define(fprime(var),s),                  /* 4 */
  loop, if abs(f(xn)) < eps then return(xn),    /* 5 */
        xn: xn - f(xn)/fprime(xn),              /* 6 */
        go (loop) )                             /* 7 */ $

\endmaximasession

Observe the list of local names at the beginning of the 
{\tt block,}
which are initialized at the same time they are declared on line 2.
Lines 3 and 4 are interesting because they define two new functions,
{\tt f}
and 
{\tt fprime}
each to have as their bodies, the values of
{\tt exp}
and {\tt s}.
The Newton iteration is more easily observed in functional
rather than {\it substitution} notation.
An even smaller version of {\tt newton}
could be defined by
using a single function for {\tt exp/diff(exp,var)}.

Let us try this last function:

\beginmaximasession
h:expand((x-1)*(x-3)*(x-5));
newton(h,x,3.5,1.0e-10);
\maximasession
(C3) h:expand((x-1)*(x-3)*(x-5));

                              3      2
(D3)                         x  - 9 x  + 23 x - 15
(C4) newton(h,x,3.5,1.0e-10);

(D4)                           2.999999999994028
\endmaximasession

You might wonder how many iterations that took.  One way is to use
the very convenient debugging feature provided by
\Max\
which allows you to watch the assignment of values to variables.
You set the variable
{\tt setcheck}
to a list of the variables you wish to watch. (or 
{\tt all}
to watch all the variables.)

\beginmaximasession
setcheck:[xn]$
newton(h,x,3.5,1.0e-10);
\maximasession
(C5) setcheck:[xn]$

(C6) newton(h,x,3.5,1.0e-10);

xn set to 3.5
xn set to 2.923076923076923
xn set to 3.000228597554008
xn set to 2.999999999994028
(D6)                           2.999999999994028
\endmaximasession

(That message {\tt [*flonum: ...]} is a message from the
garbage collector, mentioned in Section~\ref{gc}.)

That tells us that only three iterations were needed in this case.

We claimed that two functions were defined in running this
program.  To display a function using the same syntax that
you would use to type it in, you use the {\tt grind}\footnote{When 
computers were slow and programs were large, reformatting programs
took a long time. The name of a program at MIT
to {\it grind out} LISP function definitions was {\tt grindef}.  
The name was carried over to \Max.  Now, most LISP systems call this 
reformatting {\it prettyprinting}.} command.

\beginmaximasession
grind(fprime);
\maximasession
(C7) grind(fprime);


Error: cursorpos doesn't know position
Fast links are on: do (si::use-fast-links nil) for debugging
Error signalled by MACSYMA-TOP-LEVEL.
Broken at ERROR.  Type :H for Help.
\endmaximasession

\section{Part Hacking}

An important tool for applications programs in
\Max\
the ability to extract and test parts of expressions.  These are
used for the 
definition or extension of algorithms which do
various conditional manipulation of formulas.
For example, you can write
a symbolic differentiation algorithm for expressions
by applying the rules below:
$$
{d \over dx}\  x \ =\  1 \ \ \ \ \ \ \ {d \over dx}\  y \ =\  0 \ \ (y \neq x)
\eqno (1)$$
$$
{d \over dx}\  ( u + v) \ =\  {d \over dx}\  u \ +\  {d \over dx}\  v
\eqno (2)$$
$$
{d \over dx}\  ( u \cdot v) \ =\  v {d \over dx}\  u \ +\  u {d \over dx}\  v
\eqno (3)$$

The technique we shall consider for implementing a version of the
differentiation program is to take the expression apart using the 
{\tt part}
command, and use the rules above to guide the manipulation.

First, we check to see if the expression is an
atom (e.g. number, variable).
Thus we begin our differentiation program as follows:

\begin{verbatim}

newdiff(expr,var):=
        if atom(expr)=true then
                (if expr=var then 1
                             else 0)
\end{verbatim}
This fragment implements both parts of
rule 1.  If the 
{\tt if}
statement falls through to the 
{\tt else }
clause,
then we have a composite expression.  We then check what its leading
operator is by selecting its zeroth {\it part} via
{\tt part(expr,0).}
Based on its value we apply the appropriate rule.
\begin{verbatim}
        else if part(expr,0)=}+} then
             newdiff(part(expr,1),var)
                     + newdiff(part(expr,2),var)
        else if part(expr,0)=}*} then
             part(expr,2)*newdiff(part(expr,1),var)
                     + part(expr,1)*newdiff(part(expr,2),var)
        else 'newdiff(expr,var)$

\end{verbatim}
Note the last clause which returns a 'newdiff form, that is, quoted,
as a result when
the program doesn't know how to handle the leading operator.
With some thought, you
should now be able to extend newdiff to accommodate expressions including
{\tt sin} and {\tt cos} as well as
sums and products with more than two terms. 
(The \Max\ language does not at the moment have a {\tt case} 
\marginpar{Is this stiil true ????} statement, which would make 
this particular program look better.)

\section{User Representation of Data}

There is no {\it record} or {\it structure} data-type {\it constructor} in
\Max\,
but there is a way of doing something similar.  If you have used a
language like Pascal which has such a feature, you may appreciate
its usefulness. Modern dialects of LISP use such structures, but when
\Max\
was first designed and initially implemented (in 1967), this was not
in widespread use.  It also influenced the user-level programming language.

It
is natural to have to deal with collections of information in writing
programs. For example, you might wish to provide as input or output
data, a pair of expressions representing a lower and an upper bound on
a formula. One way of handling this is by making up a new {\it function}
name, say {\tt bounds}
and using it as though it were a record designator or
constructor,
but never associating it with an algorithm.  Thus {\tt bounds(1,x)}
could
be an expression representing the ordered pair $<1,{\tt x}>$.
Another example would be the use of {\tt integer\_vector(1,3,5,7)}
to designate a sequence (presumably of arbitrary length, in general),
of integers.  There is a built-in form in
\Max\,
namely a {\it list}, which can be used to deal with such collections.
It is part of the LISP heritage indicated earlier that there was initially
only one type of structure: lists of any length or element type in
\Max.
A list, when printed, looks like square-brackets
enclosing a sequence of items. Thus you could express the bounds above
as [{\tt 1,x}
]. However, if you used lists for all collections, you
would not know, on the face of it, whether [1,2] was an instance of
{\tt bounds}
or
{\tt integer\_vector.}
\Max\
allows you to designate functions you intend to treat as lists, although
you can use a different {\it header} like
{\tt bounds}
with each different type.
\Max\
makes available certain built-in
functions which can then be used on such list-like constructions
such as {\tt integer\_vector}.  These are declared by, for example,
{\tt declare(integer\_vector,list).}
The built-in operations include
{\tt cons, append, member, endcons, map, rest.}

\noindent {\tt list2:cons(element,list1)}
returns a (new) {\tt list2} which has the given
element inserted at the beginning of 
{\tt list1;} {\tt List1} and {\tt list2}
have a common {\it shared} tail.

\noindent {\tt list3:append(list1,list2)}
returns a (new) {\tt list3} which is a
combination of the two lists, sharing a common tail with list2. 
{\tt Member(element,list)}
returns true or false depending on a test
for membership.

\noindent {\tt Endcons(element,list)}
returns an (unshared) list where the given element has been
attached to the end of
given list

\noindent {\tt Map(fn,list)} returns a new list where each element
has had the function fn applied to it in turn.

\noindent {\tt Rest(list,n)} returns the part of the list beginning n items from
the front. 

These functions are parts of the fundamental repertoire of
the programming language LISP.

The use of list-like objects should be considered whenever you are
dealing with a collection of elements: a set of coordinates, a series
of coefficients, a system of equations, a set of solutions, etc.

Independent of the {\it whole list} operations above,
\Max\
has some selection and alteration operations which are available on
the same collections of data by the use of a numeric index.
If you wish to use these indexing facilities, as we will illustrate for the
notion of 
{\tt complex}
below, you {\tt declare(complex,list).}
Then, if you define a complex
number by {\tt x:complex(3,4)}
meaning that 
{\tt x}
has real part 3, and imaginary
part 4, the notation {\tt x[1]:10;}
is supported, and changes the value of
{\tt x}
to
{\tt complex(10,4).}
The declaration explains to the
\Max\
system that the data structure for
{\tt complex}
will be implemented (in effect) as a list of items, and should be decomposable
using the semantics of the
\Max\
list-handling commands.
In fact, both selection and alteration is supported, and if you set the
notation up by {\tt (real:1,imag:2)\$}
you can use the following command:
{\tt x[imag]:-x[imag]}
to change 
{\tt x}
to its complex conjugate.

An important caution must be observed.  When
\Max\
deals with compound structures, they are usually not recopied, and if
there are two names for the same object and the object is changed, then
both names refer to the changed object.
If {\tt x} and {\tt y} refer to the same {\tt complex} number, then changes to
{\tt x[real]} are also made to the corresponding component of {\tt y}.
If these items are to be kept separate, {\tt x:copylist(y);} will give {\tt x}
a different representation, but whose value is the same as {\tt y} 's.
You can then change their components separately.

\Max's built-in lists mentioned earlier, which use square-brackets, 
can be altered and selected by indexing.

There are two other compound structures in \Max\
which we mention here, which may be useful for
collections of data: arrays and matrices.
The matrix form is useful for two-dimensional rectangular tables of
data.  The matrix data format is supported by a number of special
commands oriented toward the conventional interpretation of
matrices in mathematics: inverses, determinants, etc.
Matrices can be used for other kinds of data, but you should be
cautious about using them in a manner that is too far distant from
the conventional: arithmetic operations in \Max\,
in particular, have already been defined.

Arrays are unusual in their flexibility in \Max.
They are usually treated as global tables, although they can be
declared to be local to a function; they cannot be passed around 
as parameters as is the case with matrices.  The
names of arrays may be passed from program to program, but the data
itself is not recopied, nor is it convenient to even make a copy
of the data into another array. {\it Hashed} arrays are particularly
ingenious, and have been illustrated earlier. Functions can be associated
with arrays to provide new values for entries as they are required.

At this point you should be able to make use of the
\Max\
manual to learn more details for representation of
new data types as you develop your application.
%.sh 1 More\ learning

The true programming buff may also be interested in the macro-expansion
capabilities of
\Max\
and its extensible syntax.  At this point we would discourage the use of
these facilities by novices, but encourage their use by persons willing
to experiment in providing the most versatile user-oriented packages within
the
\Max\
framework.

There is a {\it compilation} facility which allows users to translate
\Max\
code into potentially faster running code.  Since most of the time in
most programs is used by calls to LISP programs, this is usually ineffective.
In general, this should be avoided by novices and most experienced users, since
time spent on this is more wisely spent on mathematical restructuring of
the solution method, or (in the case of primarily numerical computation),
using a numerical library routine written in a suitable language.
