
% Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     - Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%
%     - Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the
%       distribution.
%
%     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
%       names of its contributors may be used to endorse or promote products
%       derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
% IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES-- LOSS OF USE, DATA, OR
% PROFITS-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


A \spadgloss{list} is a finite collection of elements in a specified
order that can contain duplicates.
A list is a convenient structure to work with because it is easy
to add or remove elements and the length need not be constant.
There are many different kinds of lists in \Language{}, but the
default types (and those used most often) are created by the
\spadtype{List} constructor.
For example, there are objects of type \spadtype{List Integer},
\spadtype{List Float} and \spadtype{List Polynomial Fraction Integer}.
Indeed, you can even have \spadtype{List List List Boolean}
(that is, lists of lists of lists of Boolean values).
You can have lists of any type of \Language{} object.

% *********************************************************************
\head{subsection}{Creating Lists}{ugxListCreate}
% *********************************************************************

The easiest way to create a list with, for example, the elements
\spad{2, 4, 5, 6} is to enclose the elements with square
brackets and separate the elements with commas.
\xtc{
The spaces after the commas are optional, but they do improve the
readability.
}{
\spadcommand{[2, 4, 5, 6]}
}
\xtc{
To create a list with the single element \spad{1}, you can use
either \spad{[1]} or the operation \spadfunFrom{list}{List}.
}{
\spadcommand{[1]}
}
\xtc{
}{
\spadcommand{list(1)}
}
\xtc{
Once created, two lists \spad{k} and \spad{m} can be
concatenated by issuing \spad{append(k,m)}.
\spadfunFrom{append}{List} does {\it not} physically join the lists,
but rather produces a new list with the elements coming from the two
arguments.
}{
\spadcommand{append([1,2,3],[5,6,7])}
}
\xtc{
Use \spadfunFrom{cons}{List} to append an element onto the front of a
list.
}{
\spadcommand{cons(10,[9,8,7])}
}

% *********************************************************************
\head{subsection}{Accessing List Elements}{ugxListAccess}
% *********************************************************************

\xtc{
To determine whether a list has any elements, use the operation
\spadfunFrom{empty?}{List}.
}{
\spadcommand{empty? [x+1]}
}
\xtc{
Alternatively, equality with explicit empty list \spadfunFrom{[]}{List} can
be tested.
}{
\spadcommand{(rest([1]) = [])@Boolean}
}

\xtc{
We'll use this in some of the following examples.
}{
\spadcommand{k := [4,3,7,3,8,5,9,2] \bound{k}}
}
\xtc{
Each of the next four expressions extracts the \spadfunFrom{first}{List}
element of \spad{k}.
}{
\spadcommand{first k \free{k}}
}
\xtc{
}{
\spadcommand{k.first \free{k}}
}
\xtc{
}{
\spadcommand{k.1 \free{k}}
}
\xtc{
}{
\spadcommand{k(1) \free{k}}
}
The last two forms generalize to \spad{k.i} and \spad{k(i)},
respectively, where
\texht{$ 1 \leq i \leq n$}{\spad{1 <= i <= n}}
and
\spad{n} equals the length of \spad{k}.
\xtc{
This length is calculated by \spadopFrom{#}{List}.
}{
\spadcommand{n := \#k \free{k}}
}
Performing an operation such as \spad{k.i} is sometimes
referred to as {\it indexing into k} or
{\it elting into k}.
The latter phrase comes about because the name of the operation
that extracts elements is called \spadfunFrom{elt}{List}.
That is, \spad{k.3} is just alternative syntax for \spad{elt(k,3)}.
It is important to remember that list indices
begin with 1.
If we issue \spad{k := [1,3,2,9,5]} then \spad{k.4}
returns \spad{9}.
It is an error to use an index that is not in the range from
\spad{1} to the length of the list.

\xtc{
The last element of a list is extracted by any of the
following three expressions.
}{
\spadcommand{last k \free{k}}
}
\xtc{
}{
\spadcommand{k.last \free{k}}
}
\xtc{
This form computes the index of the last element and then
extracts the element from the list.
}{
\spadcommand{k.(\#k) \free{k}}
}

% *********************************************************************
\head{subsection}{Changing List Elements}{ugxListChange}
% *********************************************************************

\xtc{
We'll use this in some of the following examples.
}{
\spadcommand{k := [4,3,7,3,8,5,9,2] \bound{k}}
}
\xtc{
List elements are reset by using the \spad{k.i} form on
the left-hand side of an assignment.
This expression resets the first element of \spad{k} to \spad{999}.
}{
\spadcommand{k.1 := 999 \free{k}\bound{k1}}
}
\xtc{
As with indexing into a list, it is an error to use an index
that is not within the proper bounds.
Here you see that \spad{k} was modified.
}{
\spadcommand{k \free{k1}}
}

The operation that performs the assignment of an element to a particular
position in a list is called \spadfunFromX{setelt}{List}.
This operation is {\it destructive} in that it changes the list.
In the above example, the assignment returned the value \spad{999} and
\spad{k} was modified.
For this reason, lists are called \spadgloss{mutable} objects: it is
possible to change part of a list (mutate it) rather than always returning
a new list reflecting the intended modifications.
\xtc{
Moreover, since lists can share structure, changes to one list can
sometimes affect others.
}{
\spadcommand{k := [1,2] \bound{k2}}
}
\xtc{
}{
\spadcommand{m := cons(0,k) \free{k2}\bound{m}}
}
\xtc{
Change the second element of \spad{m}.
}{
\spadcommand{m.2 := 99 \free{m}\bound{m2}}
}
\xtc{
See, \spad{m} was altered.
}{
\spadcommand{m \free{m2}}
}
\xtc{
But what about \spad{k}?
It changed too!
}{
\spadcommand{k  \free{m2 k2}}
}

% *********************************************************************
\head{subsection}{Other Functions}{ugxListOther}
% *********************************************************************

\xtc{
An operation that is used frequently in list processing is that
which returns all elements in a list after the first element.
}{
\spadcommand{k := [1,2,3] \bound{k}}
}
\xtc{
Use the \spadfunFrom{rest}{List} operation to do this.
}{
\spadcommand{rest k \free{k}}
}

\xtc{
To remove duplicate elements in a list \spad{k}, use
\spadfunFrom{removeDuplicates}{List}.
}{
\spadcommand{removeDuplicates [4,3,4,3,5,3,4]}
}
\xtc{
To get a list with elements in the order opposite to those in
a list \spad{k}, use \spadfunFrom{reverse}{List}.
}{
\spadcommand{reverse [1,2,3,4,5,6]}
}
\xtc{
To test whether an element is in a list, use \spadfunFrom{member?}{List}:
\spad{member?(a,k)} returns \spad{true} or \spad{false}
depending on whether \spad{a} is in \spad{k} or not.
}{
\spadcommand{member?(1/2,[3/4,5/6,1/2])}
}
\xtc{
}{
\spadcommand{member?(1/12,[3/4,5/6,1/2])}
}

As an exercise, the reader should determine how to get a
list containing all but the last of the elements in a given non-empty
list \spad{k}.\footnote{\spad{reverse(rest(reverse(k)))} works.}

% *********************************************************************
\head{subsection}{Dot, Dot}{ugxListDot}
% *********************************************************************

Certain lists are used so often that \Language{} provides an easy way
of constructing them.
If \spad{n} and \spad{m} are integers, then \spad{expand [n..m]}
creates a list containing \spad{n, n+1, ... m}.
If \spad{n > m} then the list is empty.
It is actually permissible to leave off the \spad{m} in the
dot-dot construction (see below).

\xtc{
The dot-dot notation can be used more than once in a list
construction and with specific elements being given.
Items separated by dots are called {\it segments.}
\index{segment}
}{
\spadcommand{[1..3,10,20..23]}
}
\xtc{
Segments can be expanded into the range of items between the
endpoints by using \spadfunFrom{expand}{Segment}.
}{
\spadcommand{expand [1..3,10,20..23]}
}
\xtc{
What happens if we leave off a number on the right-hand side of
\spadopFrom{..}{UniversalSegment}?
}{
\spadcommand{expand [1..]}
}
What is created in this case is a \spadtype{Stream} which is a
generalization of a list.
See \xmpref{Stream} for more information.
