packages feed

myTestlll-1.0.0: HSoM/Intro.lhs

%-*- mode: Latex; abbrev-mode: true; auto-fill-function: do-auto-fill -*-

%include lhs2TeX.fmt
%include myFormat.fmt

\chapter[Computer Music, Euterpea, and Haskell]{Overview of 
  Computer Music, Euterpea, and Haskell}
\label{ch:intro}

Computers are everywhere.  And so is music!  Although some might think
of the two as being at best distant relatives, in fact they share many
deep properties.  Music comes from the soul, and is inspired by the
heart, yet it has the mathematical rigor of computers.  Computers have
mathematical rigor of course, yet the most creative ideas in
mathematics and computer science come from the soul, just like music.
Both disciplines demand both left-brain and right-brain skills.  It
always surprises me how many computer scientists and mathematicians
have a serious interest in music.  It seems that those with a strong
affinity or acuity in one of these disciplines is often strong in the
other as well.

It is quite natural then to consider how the two might interact.  In
fact there is a long history of interactions between music and
mathematics, dating back to the Greeks' construction of musical scales
based on arithmetic relationships, and including many classical
composers use of mathematical structures, the formal harmonic analysis
of music, and many modern music composition techniques.  Advanced
music theory uses ideas from diverse branches of mathematics such as
number theory, abstract algebra, topology, category theory, calculus,
and so on.

There is also a long history of efforts to combine computers and
music.  Most consumer electronics today are digital, as are most forms
of audio processing and recording.  But in addition, digital musical
instruments provide new modes of expression, notation software and
sequencers have become standard tools for the working musician, and
those with the most computer science savvy use computers to explore
new modes of composition, transformation, performance, and analysis.

This textbook explores the fundamentals of computer music using a
language-centric approach.  In particular, the functional programming
language \emph{Haskell} is used to express all of the computer music
concepts.  Thus a by-product of learning computer music concepts will
be learning how to program in Haskell.  The core musical ideas are
collected into a Haskell library called \emph{Euterpea}.  The name
``Euterpea'' is derived from \emph{Euterpe}, who was one of the nine
Greek muses, or goddesses of the arts, specifically the muse of music.
A hypothetical picture of Euterpe graces the cover of this textbook.

\section{The Note vs. Signal Dichotomy}

The field of computer music has grown astronomically over the past
several decades, and the material can be structured and organized
along several dimensions.  A dimension that proves particulary useful
with respect to a programming language is one that separates
\emph{high-level} musical concerns from \emph{low-level} musical
concerns.  Since a ``high-level'' programming language---namely
Haskell---is used to program at both of these musical levels, to avoid
confusion the terms \emph{note level} and \emph{signal level} will be
used in the musical dimension.

At the \emph{note level}, a \emph{note} (i.e.\ pitch and duration) is
the lowest musical entity that is considered, and everything else is
built up from there.  At this level, in addition to conventional
representations of music, we can study interesting aspects of
so-called \emph{algorithmic composition}, including the use of
fractals, grammar-based systems, stochastic processes, and so on.
From this basis we can also study the harmonic and rhythmic
\emph{analysis} of music, although that is not currently an emphasis
in this textbook.  Haskell facilitates programming at this level
through its powerful data abstraction facilities, higher-order
functions, and declarative semantics.

In contrast, at the \emph{signal level} the focus is on the actual
sound generated in a computer music application, and thus a
\emph{signal} is the lowest entity that is considered.  Sound is
concretely represented in a digital computer by a discrete sampling of
the continuous audio signal, at a high enough rate that human ears
cannot distinguish the discrete from the continuous, usually 44,100
samples per second (the standard sampling rate used for CDs, mp3
files, and so on).  But in Euterpea, these details are hidden: signals
are treated abstractly as continuous quantities.  This greatly eases
the burden of programming with sequences of discrete values.  At the
signal level, we can study sound synthesis techniques (to simulate
the sound of a conventional instrument, say, or something completely
artificial), audio processing (e.g.\ determining the frequency
spectrum of a signal), and special effects (reverb, panning,
distortion, and so on).

Suppose for a moment that a musician is playing music using a
metro\-nome set at 96, which corresponds to 96 beats per minute.  That
means that one beat takes $\nicefrac{60}{96}$ = 0.625 seconds.  At a
stereo sampling rate of 44,100 samples per second, that in turn
translates into $2\times 0.625\times 44,100$ = 55,125 samples, and
each sample typically occupies several bytes of computer memory.  This
is typical of the minimum memory requirements of a computation at the
signal level.  In contrast, at the note level, we only need some kind
of operator or data structure that says ``play this note,'' which
requires a total of only a small handful of bytes.  This dramatic
difference highlights one of the key computational differences between
programming at the note level versus the signal level.

Of course, many computer music applications involve both the note
level \emph{and} the signal level, and indeed there needs to be a
mechanism to mediate between the two.  Although such mediation can
take many forms, it is for the most part straightforward.  Which is
another reason why the distinction between the note level and the
signal level is so natural.

This textbook begins with a treatment of the note level
(Chapters~\ref{ch:intro}-\ref{ch:MUI}) and follows with a treatment of
the signal level (Chapters~\ref{ch:signals}-\ref{ch:additive}).  If
you are interested only in the signal level, you could skip
Chapters~\ref{ch:performance}-\ref{ch:MUI}.

\section{Basic Principles of Programming}

Programming, in its broadest sense, is \emph{problem solving}.  It
begins by recognizing problems that can and should be solved using a
digital computer.  Thus the first step in programming is answering the
question, ``What problem am I trying to solve?''

% ``Solving the wrong problem'' is a phrase often heard in many
% contexts, and we certainly do not want to be victims of that crime.

% \footnote{Of course, not all problems fall into this category, and
% some problems are solved (or are attempted to be solved) using
% computers that probably should not be.  But I will avoid this
% digression.}

Once the problem is understood, a solution must be found.  This may
not be easy, of course, and in fact you may discover several
solutions, so a way to measure success is needed.  There are various
dimensions in which to do this, including correctness (``Will I get
the right answer?'') and efficiency (``Will it run fast enough, or use
too much memory?'').  But the distinction of which solution is better
is not always clear, since the number of dimensions can be large, and
programs will often excel in one dimension and do poorly in others.
For example, there may be one solution that is fastest, one that uses
the least amount of memory, and one that is easiest to understand.
Deciding which to choose can be difficult, and is one of the more
interesting challenges in programming.

The last measure of success mentioned above---clarity of a
program---is somewhat elusive: difficult to quantify and measure.
Nevertheless, in large software systems clarity is an especially
important goal, since such systems are worked on by many people over
long periods of time, and evolve considerably as they mature.  Having
easy-to-understand code makes it much easier to modify.

In the area of computer music, there is another reason why clarity is
important: namely, that the code often represents the author's thought
process, musical intent, and artistic choices.  A conventional
musical score does not say much about what the composer thought as she
wrote the music, but a program often does.  So when you write your
programs, write them for others to see, and aim for elegance and beauty,
just like the musical result that you desire.

Programming is itself a creative process.  Sometimes programming
solutions (or artistic creations) come to mind all at once, with
little effort.  More often, however, they are discovered only after
lots of hard work!  We may write a program, modify it, throw it away
and start over, give up, start again, and so on.  It is important to
realize that such hard work and reworking of programs is the norm, and
in fact you are encouraged to get into the habit of doing so.  Do not
always be satisfied with your first solution, and always be prepared
to go back and change or even throw away those parts of your program
that you are not happy with.

\section{Computation by Calculation}
\index{computation by calculation}

It is helpful when learning a new programming language to have a good
grasp of how programs in that language are executed---in other words,
an understanding of what a program \emph{means}.  The execution of
Haskell programs is perhaps best understood as \emph{computation by
  calculation}.  Programs in Haskell can be viewed as \emph{functions}
whose input is that of the problem being solved, and whose output is
the desired result---and the behavior of functions can be effectively
understood as computation by calculation.

An example involving numbers might help to demonstrate these ideas.
Numbers are used in many applications, and computer music is no
exception.  For example, integers might be used to represent pitch,
and floating-point numbers might be used to perform calculations
involving frequency or amplitude.

Suppose we wish to perform an arithmetic calculation such as
$3\times(9+5)$.  In Haskell this would be written as |3*(9+5)|, since
most standard computer keyboards and text editors do not recognize the
special symbol $\times$.  The result can be calculated as follows:
\begin{spec}
3*(9+5) 
==> 3*14 
==> 42
\end{spec}
It turns out that this is not the only way to compute the result, as
evidenced by this alternative calculation:\footnote{This assumes that
  multiplication distributes over addition in the number system being
  used, a point that will be returned to later in the text.}
\begin{spec}
3*(9+5) 
==> 3*9 + 3*5 
==> 27 + 3*5 
==> 27+15 
==> 42
\end{spec}
\index{efficiency}% 

Even though this calculation takes two extra steps, it at least gives
the same, correct answer.  Indeed, an important property of each and
every program written in Haskell is that it will always yield the same
answer when given the same inputs, regardless of the order chosen to
perform the calculations.\footnote{This is true as long as a
  non-terminating sequence of calculations is not chosen, another
  issue that will be addressed later.} This is precisely the
mathematical definition of a \emph{function}: for the same inputs, it
always yields the same output.

On the other hand, the first calculation above required fewer steps
than the second, and thus it is said to be more \emph{efficient}.
Efficiency in both space (amount of memory used) and time (number of
steps executed) is important when searching for solutions to problems.
Of course, if the computation returns the wrong answer, efficiency is
a moot point.  In general it is best to search first for an elegant
(and correct!)  solution to a problem, and later refine it for better
performance.  This strategy is sometimes summarized as, ``Get it right
first!''

The above calculations are fairly trivial, but much more sophisticated
computations will be introduced soon enough.  For starters---and to
introduce the idea of a Haskell function---the arithmetic operations
performed in the previous example can be \emph{generalized} by
defining a function to perform them for any numbers |x|, |y|, and |z|:
\indexhs{simple}
\begin{spec}
simple x y z = x*(y+z)
\end{spec}
This equation defines |simple| as a function of three
\emph{arguments}, |x|, |y|, and |z|.  In mathematical notation this
definition might be written differently, such as one of the following:
\[\begin{array}{l}
{\it simple}(x,y,z) = x\times(y+z)\\
{\it simple}(x,y,z) = x\cdot(y+z)\\
{\it simple}(x,y,z) = x(y+z)
\end{array}\]
In any case, it should be clear that ``|simple 3 9 5|'' is the same
as ``|3*(9+5)|.''  In fact the proper way to calculate the result is:
\begin{spec}
simple 3 9 5 
==> 3*(9+5)
==> 3*14
==> 42
\end{spec}
\index{unfold (in a calculation)}
The first step in this calculation is an example of \emph{unfolding} a
function definition: 3 is substituted for |x|, 9 for |y|, and 5
for |z| on the right-hand side of the definition of |simple|.
This is an entirely mechanical process, not unlike what the computer
actually does to execute the program.

|simple 3 9 5| is said to \emph{evaluate} to 42.  To express the fact
that an expression $e$ evaluates (via zero, one, or possibly many more
steps) to the value $v$, we will write $e \Longrightarrow v$ (this arrow
is longer than that used earlier).  So we can say directly, for
example, that |simple 3 9 5 ===> 42|, which should be read ``|simple 3
9 5| evaluates to 42.''

With |simple| now suitably defined, we can repeat the sequence of
arithmetic calculations as often as we like, using different values
for the arguments to |simple|.  For example, 
|simple 4 3 2 ===> 20|.

We can also use calculation to \emph{prove properties} about
programs.  For example, it should be clear that for any |a|, |b|, and
|c|, |simple a b c| should yield the same result as |simple a c b|.
For a proof of this, we calculate \emph{symbolically}; that is,
using the symbols |a|, |b|, and |c| rather than concrete numbers such
as 3, 5, and 9:
\begin{spec}
simple a b c 
==> a*(b+c) 
==> a*(c+b)
==> simple a c b
\end{spec}
Note that the same notation is used for these symbolic steps as for
concrete ones.  In particular, the arrow in the notation reflects the
direction of formal reasoning, and nothing more.  In general, if |e1
==> e2|, then it is also true that |e2 ==> e1|.

These symbolic steps are also referred to as as ``calculations,'' even
though the computer will not typically perform them when executing a
program (although it might perform them \emph{before} a program is run
if it thinks that it might make the program run faster).  The second
step in the calculation above relies on the commutativity of addition
(namely that, for any numbers $x$ and $y$, $x+y=y+x$).  The third step
is the reverse of an unfold step, and is appropriately called a
\emph{fold} calculation.  \index{fold (in a calculation)} It would be
particularly strange if a computer performed this step while executing
a program, since it does not seem to be headed toward a final answer.
But for proving properties about programs, such ``backward reasoning''
is quite important.

When we wish to spell out the justification for each step, whether
symbolic or concrete, a calculation can be annotated with more detail,
as in:
\begin{spec}
simple a b c
==> { unfold }
a*(b+c)
==> { commutativity }
a*(c+b)
==> { fold }
simple a c b
\end{spec}
In most cases, however, this will not be necessary.

Proving properties of programs is another theme that will be repeated
often in this text.  Computer music applications often have some kind
of a mathematical basis, and that mathematics must be reflected
somewhere in our programs.  But how do we know if we got it right?
Proof by calculation is one way to connect the problem specification
with the program solution.

More broadly speaking, as the world begins to rely more and more on
computers to accomplish not just ordinary tasks such as writing term
papers, sending email, and social networking, but also life-critical
tasks such as controlling medical procedures and guiding spacecraft,
then the correctness of programs gains in importance.  Proving complex
properties of large, complex programs is not easy---and rarely if ever
done in practice---but that should not deter us from proving simpler
properties of the whole system, or complex properties of parts of the
system, since such proofs may uncover errors, and if not, will at
least give us confidence in our effort.

If you are someone who is already an experienced programmer, the idea
of computing \emph{everything} by calculation may seem odd at best,
and na\"{i}ve at worst.  How do we write to a file, play a sound,
draw a picture, or respond to mouse-clicks?  If you are wondering
about these things, it is hoped that you have patience reading the
early chapters, and that you find delight in reading the later
chapters where the full power of this approach begins to shine.

In many ways this first chapter is the most difficult, since it
contains the highest density of new concepts.  If the reader has
trouble with some of the concepts in this overview chapter, keep in
mind that most of them will be revisited in later chapters.  And do not
hesitate to return to this chapter later to re-read difficult
sections; they will likely be much easier to grasp at that time.

\syn{In the remainder of this textbook the need will often arise to
  explain some aspect of Haskell in more detail, without distracting
  too much from the primary line of discourse.  In those circumstances
  the explanations will be offset in a shaded box such as this one,
  proceeded with the word ``Details.''}

\vspace{.1in}\hrule

\begin{exercise}{\em
Write out all of the steps in the calculation of the value of
\begin{spec}
simple (simple 2 3 4) 5 6
\end{spec}
}
\end{exercise}

\begin{exercise}{\em
Prove by calculation that |simple (a-b) a b ===>| $a^2 - b^2$.}
\end{exercise}

\vspace{.1in}\hrule

\section{Expressions and Values}
\label{sec:expressions}

In Haskell, the entities on which calculations are performed are
called \emph{\indexwd{expressions}}, and the entities that result from
a calculation---i.e.\ ``the answers''---are called
\emph{\indexwd{values}}.  It is helpful to think of a value just as an
expression on which no more calculation can be carried out---every
value is an expression, but not the other way around.

Examples of expressions include \emph{atomic} (meaning, indivisible)
values such as the integer |42| and the character |'a'|, which are
examples of two \emph{primitive} atomic values in Haskell.  The next
chapter introduces examples of \emph{constructor} atomic values, such
as the musical notes |C|, |D|, |Ef|, |Fs|, etc., which in standard
music notation are written C, D, E$\flat$, F$\sharp$, etc., and are
pronounced C, D, E-flat, F-sharp, etc.  (In music theory, note names
are called \emph{pitch classes}.).

In addition, there are \emph{structured} expressions (i.e., made from
smaller pieces) such as the \emph{\indexwd{list}} of pitches
|[C,D,Ef]|, the character/number \emph{\indexwd{pair}} |('b',4)|
(lists and pairs are different in a subtle way, to be described
later), and the string |"Euterpea"|.  Each of these structured
expressions is also a value, since by themselves there is no further
calculation that can be carried out.  As another example, |1+2| is an
expression, and one step of calculation yields the expression |3|,
which is a value, since no more calculations can be performed.  As a
final example, as was expained earlier, the expression |simple 3 9 5|
evaluates to the value 42.

Sometimes, however, an expression has only a never-ending
sequence of calculations.  For example, if |x| is defined as:
\begin{spec}
x = x + 1
\end{spec}
then here is what happens when trying to calculate the value of |x|:
\begin{spec}
x 
==> x + 1
==> (x + 1) + 1
==> ((x + 1) + 1) + 1
==> (((x + 1) + 1) + 1) + 1
...
\end{spec}
Similarly, if a function |f| is defined as:
\begin{spec}
f x = f (x-1)
\end{spec}
then an expression such as |f 42| runs into a similar problem:
\begin{spec}
f 42
==> f 41
==> f 40
==> f 39
...
\end{spec}
Both of these clearly result in a never-ending sequence of
calculations.  Such expressions are said to not terminate, or
\emph{diverge}.  In such cases the symbol |bottom|\index{bottom},
pronounced ``bottom,'' is used to denote the value of the expression.
This means that every diverging computation in Haskell denotes the
same |bottom| value,\footnote{Technically, each type has its own
  version of |bottom|.} reflecting the fact that, from an observer's
point of view, there is nothing to distinguish one diverging
computation from another.

\section{Types}

Every expression (and therefore every value) also has an associated
\emph{\indexwd{type}}.  It is helpful to think of types as sets of
expressions (or values), in which members of the same set have much in
common.  Examples include the primitive atomic types
\indexwdhs{Integer} (the set of all integers) and \indexwdhs{Char}
(the set of all characters), the user-defined atomic type |PitchClass|
(the set of all pitch classes, i.e.\ note names), as well as the
structured types |[Integer]| and |[PitchClass]| (the sets of all lists
of integers and lists of pitch classes, respectively), and |String|
(the set of all Haskell strings).

The association of an expression or value with its type is very
useful, and there is a special way of expressing it in Haskell.
Using the examples of values and types above:
\begin{spec}
D           :: PitchClass
42          :: Integer
'a'         :: Char
"Euterpea"  :: String
[C,D,Ef]    :: [PitchClass]
('b',4)     :: (Char,Integer)
\end{spec}
\indexhs{::}
Each association of an expression with its type is called a \emph{type
  signature}.

\index{case sensitivity}

\syn{Note that the names of specific types are capitalized, such as
  |Integer| and |Char|, as are the names of some atomic values such as
  |D| and |Fs|.  These will never be confused in context, since things
  to the right of ``|::|'' are types, and things to the left are
  values.  Note also that user-defined names of values are \emph{not}
  capitalized, such as |simple| and |x|.  This is not just a
  convention: it is required when programming in Haskell.  In
  addition, the case of the other characters matters, too.  For
  example, |test|, |teSt|, and |tEST| are all distinct names for
  values, as are |Test|, |TeST|, and |TEST| for types.}

\syn{Literal characters are written enclosed in single forward quotes
  (apostrophes), as in |'a'|, |'A'|, |'b'|, |','|, |'!'|, |' '| (a
  space), and so on.  (There are some exceptions, however; see the
  Haskell Report for details.)  Strings are written enclosed in double
  quote characters, as in |"Euterpea"| above.  The connection between
  characters and strings will be explained in a later chapter.

The ``|::|'' should be read ``has type,'' as in ``42 has type
|Integer|.''  Note that square braces are used both to construct a
list value (the left-hand side of |(::)| above), and to describe its
type (the right-hand side above).  Analogously, the round braces used
for pairs are used in the same way.  But also note that all of the
elements in a list, however long, must have the same type, whereas the
elements of a pair can have different types.}

Haskell's \emph{type system} ensures that Haskell programs are 
\emph{\indexwd{well-typed}}; that is, that the programmer has not
mismatched types in some way.  For example, it does not make much
sense to add together two characters, so the expression |'a' + 'b'| is
\emph{\indexwd{ill-typed}}.  The best news is that Haskell's type
system will tell you if your program is well-typed \emph{before you run
  it}.  This is a big advantage, since most programming errors are
manifested as type errors.

%% The idea of dividing the world of values into types should be a
%% familiar idea to most people.  We do it all of the time for just about
%% every kind of object you can think of.  Take boxes, for example.  Just
%% as we have integers and reals, lists and tuples, etc., we also have
%% large boxes and small boxes, cardboard boxes and wooden boxes, and so
%% on.  And just as we have lists of integers and lists of characters, we
%% also have boxes of nails and boxes of shoes.  And just as we would not
%% expect to be able to take the square of a list, or add two characters,
%% we would not expect to be able to use a box to pay for our groceries.

%% Types help us to make sense of the world by organizing it into groups
%% of common shape, size, functionality, etc.  The same is true for
%% programming, where types help us to organize values into groups of
%% common shape, size, and functionality, amongst other things.  Of
%% course, the kinds of commonality between values will not be the same
%% as those between objects in the real world, and in general we will be
%% more restricted---and more formal---about just what we can say about
%% types and how we say it.

% Nevertheless, the analogy holds.

\section{Function Types and Type Signatures}

\index{function!type||(} What should the \indexwd{type} of a function
be?  It seems that it should at least convey the fact that a function
takes values of one type---|T1|, say---as input, and returns values of
(possibly) some other type---|T2|, say---as output.  In Haskell this
is written |T1 -> T2|, and such a function is said to ``map values of
type |T1| to values of type |T2|.''\footnote{In mathematics |T1| is
  called the \emph{domain} of the function, and |T2| the
  \emph{range}.}  If there is more than one argument, the notation is
extended with more arrows.  For example, if the intent is that the
function |simple| defined in the previous section has type
|Integer->Integer->Integer->Integer|, we can include a type signature
with the definition of |simple|: \index{type!signature}
\begin{spec}
simple         :: Integer -> Integer -> Integer -> Integer
simple x y z   = x*(y+z)
\end{spec}
\syn{When writing Haskell programs using a typical text editor, there
  typically will not be nice fonts and arrows as in |Integer ->
  Integer|.  Rather, you will have to type {\tt Integer -> Integer}.}

\index{type!inference} Haskell's type system also ensures that
user-supplied type signatures such as this one are correct.  Actually,
Haskell's type system is powerful enough to allow us to avoid writing
any type signatures at all, in which case the type system is said to
\emph{infer} the correct types.\footnote{There are a few exceptions to
  this rule, and in the case of |simple| the inferred type is actually
  a bit more general than that written above.  Both of these points
  will be returned to later.}  Nevertheless, judicious placement of
type signatures, as was done for |simple|, is a good habit, since type
signatures are an effective form of documentation and help bring
programming errors to light.  In fact, it is a good habit to first
write down the type of each function you are planning to define, as a
first approximation to its full specification---a way to grasp its
overall functionality before delving into its details.

\index{function!application}
The normal use of a function is referred to as \emph{function
  application}.  For example, |simple 3 9 5| is the application of
the function |simple| to the arguments 3, 9, and 5.  Some
functions, such as |(+)|, are applied using what is known as
\emph{\indexwd{infix} syntax}; that is, the function is written
between the two arguments rather than in front of them (compare
|x+y| to |f x y|).

\syn{Infix functions are often called \emph{\indexwd{operators}}, and
are distinguished by the fact that they do not contain any numbers or
letters of the alphabet.  Thus |^!| and |*#:| are infix
operators, whereas |thisIsAFunction| and |f9g| are not (but are
still valid names for functions or other values).  The only exception
to this is that the symbol \emph{'} is considered to be alphanumeric;
thus |f'| and |one's| are valid names, but not operators.

In Haskell, when referring to an infix operator as a value, it is enclosed
in parentheses, such as when declaring its type, as in:
\begin{spec}
(+) :: Integer -> Integer -> Integer
\end{spec}
Also, when trying to understand an expression such as |f x + g y|,
there is a simple rule to remember: function application \emph{always}
has ``higher \indexwd{precedence}'' than operator application, so that
|f x + g y| is the same as |(f x) + (g y)|.

Despite all of these syntactic differences, however, operators are
still just functions.}
\index{function!type||)}

\vspace{.1in}\hrule

\begin{exercise}{\em
Identify the well-typed expressions in the following, and, for each,
give its proper type:
\begin{spec}
[ A, B, C ]
[ D, 42 ]
( -42, Ef )
[ ('a',3), ('b',5) ]
simple 'a' 'b' 'c'
( simple 1 2 3, simple )
["I","love","Euterpea"]
\end{spec}
For those expressions that are ill-typed, explain why.
}
\end{exercise} 
\out{
\begin{spec}
[ (2,3), (4,5) ]
[ D, 42 ]
( Ef, -42 )
simple 'a' 'b' 'c'
( simple 1 2 3, simple )
["hello","world"]
\end{spec}
}

\vspace{.1in}\hrule

\section{Abstraction, Abstraction, Abstraction}
\label{sec:abstraction}
\index{abstraction||(}

The title of this section is the answer to the question: ``What are
the three most important ideas in programming?''  Webster defines the
verb ``abstract'' as follows:
\begin{quote}
{\bf abstract}, \emph{vt} (1) remove, separate (2) to consider apart
from application to a particular instance.
\end{quote}
In programming this happens when a pattern repeats itself and we wish
to ``separate'' that pattern from the ``particular instances'' in
which it appears.  In this textbook this process is called the
\emph{abstraction principle}.\index{abstraction!principle} The
following sections introduce several different kinds of abstraction,
using examples involving both simple numbers and arithmetic (things
everyone should be familiar with) as well as musical examples (that
are specific to Euterpea).

\subsection{Naming}
\index{abstraction!naming||(}

One of the most basic ideas in programming---for that matter, in every
day life---is to \emph{name} things.  For example, we may wish to give
a name to the value of $\pi$, since it is inconvenient to retype (or
remember) the value of $\pi$ beyond a small number of digits.  In
mathematics the greek letter $\pi$ in fact \emph{is} the name for this
value, but unfortunately we do not have the luxury of using greek
letters on standard computer keyboards and/or text editors.  So in
Haskell we write:
\begin{spec}
pi  :: Double
pi  = 3.141592653589793
\end{spec}
to associate the name |pi| with the number 3.141592653589793.  The
type signature in the first line declares |pi| to be a
\emph{double-precision floating-point number}, which mathematically
and in Haskell is distinct from an integer.\footnote{We will have more
  to say about floating-point numbers later.} Now the name |pi| can be
used in expressions whenever it is in scope; it is an abstract
representation, if you will, of the number 3.141592653589793.
Furthermore, if there is ever a need to change a named value (which
hopefully will not ever happen for |pi|, but could certainly happen
for other values), we would only have to change it in one place,
instead of in the possibly large number of places where it is used.

For a simple musical example, note first that in music theory, a
\emph{pitch} consists of a \emph{pitch class} and an \emph{octave}.
For example, in Euterpea we simply write |(A,4)| to represent the
pitch class |A| in the fourth octave.  This particular note is called
``concert A'' (because it is often used as the note to which an
orchestra tunes its instruments) or ``A440'' (because its frequency is
440 cycles per second).  Because this particular pitch is so common,
it may be desirable to give it a name, which is easily done in
Haskell, as was done above for $\pi$:
\begin{spec}
concertA, a440 :: (PitchClass, Octave)
concertA  = (A,4)  -- concert A
a440      = (A,4)  -- A440
\end{spec}

\syn{This example demonstrates the use of program {\em
    \indexwd{comments}}.  Any text to the right of ``{\tt --}'' till
  the end of the line is considered to be a programmer comment, and is
  effectively ignored.  Haskell also permits {\em nested} comments
  that have the form |{- this is a comment -}| and can appear anywhere
  in a program, including across multiple lines.}

This example demonstrates the (perhaps obvious) fact that several
different names can be given to the same value---just as your brother
John might have the nickname ``Moose.''  Also note that the name
|concertA| requires more typing than |(A,4)|; nevertheless, it has
more mnemonic value, and, if mistyped, will more likely result in a
syntax error.  For example, if you type ``|concrtA|'' by mistake, you
will likely get an error saying, ``Undefined variable,'' whereas if
you type ``|(A,5)|'' you will not.

\syn{This example also demonstrates that two names having the same
  type can be combined into the same type signature, separated by a
  comma.  Note finally, as a reminder, that these are names of values,
  and thus they both begin with a lowercase letter.}

Consider now a problem whose solution requires writing some larger
expression more than once.  For example:
\begin{spec}
x  :: Float
x  = f (pi*r**2) + g (pi*r**2)
\end{spec}

\syn{|(**)| is Haskell's floating-point exponentiation operator.  Thus
  |pi*r**2| is analogous to $\pi r^2$ in mathematics.  |(**)| has
  higher precedence than |(*)| and the other binary arithmetic
  operators in Haskell.}

Note in the definition of |x| that the expression |pi*r**2|
(presumably representing the area of a circle whose radius is |r|) is
repeated---it has two instances---and thus, applying the abstraction
principle, it can be separated from these instances.  From the
previous examples, doing this is straightforward---it is called
\emph{naming}---so we might choose to rewrite the single equation
above as two:
\begin{spec}
area  = pi*r**2
x     = f area + g area
\end{spec}
If, however, the definition of |area| is not intended for use
elsewhere in the program, then it is advantageous to ``hide'' it
within the definition of |x|.  This will avoid cluttering up the
namespace, and prevents |area| from clashing with some other value
named |area|.  To achieve this, we could simply use a \indexwdkw{let}
expression:
\begin{spec}
x =  let area = pi*r**2
     in f area + g area
\end{spec}
A {\bf let} expression restricts the \emph{visibility} of the names
that it creates to the internal workings of the {\bf let} expression
itself.  For example, if we were to write:
\begin{spec}
area  = 42
x     =  let area = pi*r**2
         in f area + g area
\end{spec}
then there is no conflict of names---the ``outer'' |area| is
completely different from the ``inner'' one enclosed in the {\bf let}
expression.  Think of the inner |area| as analogous to the first name
of someone in your household.  If your brother's name is ``John'' he
will not be confused with John Thompson who lives down the street when
you say, ``John spilled the milk.''

So you can see that naming---using either top-level equations or
equations within a {\bf let} expression---is an example of the
abstraction principle in action.  
%% It is often the case, of course, that we \emph{anticipate} the need for
%% abstraction; for example, directly writing down the final solution
%% above, because we knew that we would need to use the expression
%% |a-b+2| more than once.  
\index{abstraction!naming||)}

\syn{An equation such as |c = 42| is called a
\emph{\indexwd{binding}}.  A simple rule to remember when programming in
Haskell is never to give more than one binding for the same name in a
context where the names can be confused, whether at the top level of
your program or nestled within a |let| expression.  For example,
this is not allowed:
\begin{spec}
a  = 42
a  = 43
\end{spec}
nor is this:
\begin{spec}
a  = 42
b  = 43
a  = 44
\end{spec}
}

% (On the other hand, as you will soon see, functions can be defined
% with multiple equations, each defining the function's behavior on a
% different kind of argument.  But in such cases all of the equations
% for the same function must appear together (one after the other).)

\subsection{Functional Abstraction}
\label{sec:fun-abstract}
\index{abstraction!functional||(}

The design of functions such as |simple| can be viewed as the
abstraction principle in action.  To see this using the example above
involving the area of a circle, suppose the original program looked
like this:
\begin{spec}
x  :: Float
x  = f (pi*r1**2) + g (pi*r2**2)
\end{spec}
Note that there are now two areas involved---one of a circle whose
radius is |r1|, the other |r2|.  Now the expressions in parentheses
have a \emph{repeating pattern of operations}.  In discerning the
nature of a repeating pattern it is sometimes helpful to first identify
those things that are \emph{not} repeating, i.e.\ those things that
are \emph{changing}.  In the case above, it is the radius that is
changing.  A repeating pattern of operations can be abstracted as a
\emph{function} that takes the changing values as arguments.  Using
the function name |areaF| (for ``area function'') we can write:
\begin{spec}
x  =  let areaF r = pi*r**2
      in f (areaF r1) + g (areaF r2)
\end{spec}
This is a simple generalization of the previous example, where the
function now takes the ``variable quantity''---in this case the
radius---as an argument.  A very simple proof by calculation, in which
|areaF| is unfolded where it is used, can be given to demonstrate that
this program is equivalent to the old.

This application of the abstraction principle is called
\emph{functional abstraction}, since a sequence of operations is
abstracted as a \emph{function} such as |areaF|.  

For a musical example, a few more concepts from Euterpea are first
introduced, concepts that are addressed more formally in the next
chapter:
\begin{enumerate}
\item
In music theory a \emph{note} is a \emph{pitch} combined with a
\emph{duration}.  Duration is measured in beats, and in Euterpea has
type |Dur|.  A note whose duration is one beat is called a whole note,
one with duration $\nicefrac{1}{2}$ is called a half note, and so on.
A note in Euterpea is the smallest entity, besides a rest, that is
actually a performable piece of music, and its type is |Music Pitch|
(other variations of this type will be introduced in later chapters).

\item
In Euterpea there are functions:
\begin{spec}
note  :: Dur -> Pitch -> Music Pitch
rest  :: Dur -> Music Pitch
\end{spec}
such that |note d p| is a note whose duration is |d| and pitch is |p|,
and |rest d| is a rest with duration |d|.  For example, |note (1/4)
(A,4)| is a quarter note concert A.

\item
In Euterpea the following infix operators combine smaller |Music|
values into larger ones:
\begin{spec}
(:+:)  :: Music Pitch -> Music Pitch -> Music Pitch
(:=:)  :: Music Pitch -> Music Pitch -> Music Pitch
\end{spec}
Intuitively:
\begin{itemize}
\item |m1 :+: m2| is the music value that represents the playing of
  |m1| followed by |m2|.
\item |m1 :=: m2| is the music value that represents the playing of
  |m1| and |m2| simultaneously.
\end{itemize}

\item
Eutperepa also has a function |trans :: Int -> Pitch -> Pitch|
such that |trans i p| is a pitch that is |i| semitones (half steps, or
steps on a piano) higher than |p|.
\end{enumerate}

Now for the example.  Consider the simple melody:
\begin{spec}
note qn p1 :+: note qn p2 :+: note qn p3
\end{spec}
where |qn| is a quarter note:
\begin{spec}
qn = 1/4
\end{spec}
Suppose we wish to harmonize each note with a note played a minor
third lower.  In music theory, a minor third corresponds to three
semitones, and thus the harmonized melody can be written as:
\begin{spec}
mel =  (note qn p1 :=: note qn (trans (-3) p1)) !:+: 
       (note qn p2 :=: note qn (trans (-3) p2)) !:+: 
       (note qn p3 :=: note qn (trans (-3) p3))
\end{spec}

Note as in the previous example a repeating pattern of
operations---namely, the operations that harmonize a single note with
a note three semitones below it.  As before, to abstract a sequence of
operations such as this, a function can be defined that takes the
``variable quantities''---in this case the pitch---as arguments.  We
can take this one step further, however, by noting that in some other
context we might wish to vary the duration.  Recognizing this is to
\emph{anticipate} the need for abstraction.  Calling this function
|hNote| (for ``harmonize note'') we can then write:
\begin{spec}
hNote      :: Dur -> Pitch -> Music Pitch
hNote d p  = note d p :=: note d (trans (-3) p)
\end{spec}
There are three instances of the pattern in |mel|, each of which can
be replaced with an application of |hNote|.  This leads to:
\begin{spec}
mel  :: Music Pitch
mel  = hNote qn p1 :+: hNote qn p2 :+: hNote qn p3
\end{spec}
Again using the idea of unfolding described earlier in this chapter,
it is easy to prove that this definition is equivalent to the previous
one.

As with |areaF|, this use of |hNote| is an example of functional
abstraction.  In a sense, functional abstraction can be seen as a
generalization of naming.  That is, |area r1| is just a name for
|pi*r1**2|, |hNote d p| is just a name for |note d p :=: note d
(trans (-3) p)|, and so on.  Stated another way, named quantities
such as |area|, |pi|, |concertA|, and |a440| defined earlier can be
thought of as functions with no arguments.

Of course, the definition of |hNote| could also be hidden within |mel|
using a |let| expression as was done in the previous example:
\begin{spec}
mel  :: Music Pitch
mel  =  let hNote d p = note d p :=: note d (trans (-3) p)
        in hNote qn p1 :+: hNote qn p2 :+: hNote qn p3
\end{spec}

\subsection{Data Abstraction}
\label{sec:basic-list-abstraction}
\index{abstraction!data||(}

The value of |mel| is the sequential composition of three harmonized
notes.  But what if in another situation we must compose together
five harmonized notes, or in other situations even more?  In
situations where the number of values is uncertain, it is useful to
represent them in a \emph{data structure}.  For the example at hand, a
good choice of data structure is a \emph{\indexwd{list}}, briefly
introduced earlier, that can have any length.  The use of a data
structure motivated by the abstraction principle is one form of
\emph{data abstraction}.

Imagine now an entire list of pitches, whose length is not known at the
time the program is written.  What now?  It seems that a function is
needed to convert a list of pitches into a sequential composition of
harmonized notes.  Before defining such a function, however, there is
a bit more to say about lists.

Earlier the example |[C,D,Ef]| was given, a list of pitch classes
whose type is thus |[PitchClass]|.  A list with \emph{no} elements
is---not surprisingly---written |[]|, and is called the \emph{empty
  list}.

To add a single element |x| to the front of a list |xs|, we write
|x:xs| in Haskell.  (Note the naming convention used here; |xs| is the
plural of |x|, and should be read that way.)  For example, |C :
[D,Ef]| is the same as |[C,D,Ef]|.  In fact, this list is equivalent
to |C:(D:(Ef:[]))|, which can also be written |C:D:Ef:[]| since the
infix operator |(:)| is right associative.  \index{associativity}

\syn{In mathematics we rarely worry about whether the notation
  $a+b+c$ stands for $(a+b)+c$ (in which case $+$ would be ``left
  associative'') or $a+(b+c)$ (in which case $+$ would ``right
  associative'').  This is because in situations where the parentheses
  are left out it is usually the case that the operator is
  \emph{mathematically} associative, meaning that it does not matter
  which interpretation is chosen.  If the interpretation \emph{does}
  matter, mathematicians will include parentheses to make it clear.
  Furthermore, in mathematics there is an implicit assumption that
  some operators have higher \emph{precedence} than others; for
  example, $2\times a + b$ is interpreted as $(2\times a) + b$, not $2
  \times (a+b)$.

In many programming languages, including Haskell, each operator is
defined to have a particular precedence level and to be left
associative, right associative, or to have no associativity at all.
For arithmetic operators, mathematical convention is usually followed;
for example, |2*a+b| is interpreted as |(2*a)+b| in Haskell.  The
predefined list-forming operator |(:)| is defined to be right
associative.  Just as in mathematics, this associativity can be
overridden by using parentheses: thus |(a:b):c| is a valid Haskell
expression (assuming that it is well-typed; it must be a list of
lists), and is very different from |a:b:c|.  A way to specify the
precedence and associativity of user-defined operators will be
discussed in a later chapter.}

%% [consider eliminating the next paragraph]

%% Examples of predefined functions defined on lists in Haskell include
%% \indexwdhs{head} and \indexwdhs{tail}, which return the ``head'' and
%% ``tail'' of a list, respectively.  That is, |head (x:xs) ==> x| and
%% |tail (x:xs) ==> xs| (we will define these two functions formally
%% in Section \ref{sec:poly-types}).  Another example is the function
%% |(++)| which \emph{concatenates}, or \emph{appends}, together its two
%% list arguments.  For example, 
%% |[1,2,3] ++ [4,5,6] ==> [1,2,3,4,5,6]| (|(++)| will be defined
%% in Section \ref{sec:append}).  \indexhs{(++)}

Returning now to the problem of defining a function (call it |hList|)
to turn a list of pitches into a sequential composition of harmonized
notes, we should first express what its type should be:
\begin{spec}
hList :: Dur -> [Pitch] -> Music Pitch
\end{spec}
To define its proper behavior, it is helpful to consider, one by one,
all possible cases that could arise on the input.  First off, the list
could be empty, in which case the sequential composition should be a
|Music Pitch| value that has zero duration.  So:
\begin{spec}
hList d []     = rest 0
\end{spec}

The other possibility is that the list \emph{is not} empty---i.e.\ it
contains at least one element, say |p|, followed by the rest of the
elements, say |ps|.  In this case the result should be the
harmonization of |p| followed by the sequential composition of the
harmonization of |ps|.  Thus:
\begin{spec}
hList d (p:ps) = hNote d p :+: hList d ps
\end{spec}
Note that this part of the definition of |hList| is
\emph{recursive}---it refers to itself!  But the original
problem---the harmonization of |p:ps|---has been reduced to the
harmonization of |p| (previously captured in the function |hNote|) and
the harmonization of |ps| (a slightly smaller problem than the
original one).

Combining these two equations with the type signature yields the
complete definition of the function |hList|:
\begin{spec}
hList           :: Dur -> [Pitch] -> Music Pitch
hList d []      = rest 0
hList d (p:ps)  = hNote d p :+: hList d ps
\end{spec}
\index{pattern!matching}

Recursion is a powerful technique that will be used many times in this
textbook.  It is also an example of a general problem-solving
technique where a large problem is broken down into several smaller
but similar problems; solving these smaller problems one-by-one leads
to a solution to the larger problem.  \index{recursion}

\syn{Although intuitive, this example highlights an important aspect
of Haskell: \emph{pattern matching}.  The left-hand sides of
the equations contain \emph{patterns} such as |[]| and |x:xs|.
When a function is applied, these patterns are \emph{matched} against
the argument values in a fairly intuitive way (|[]| only matches
the empty list, and |p:ps| will successfully match any list with at
least one element, while naming the first element |p| and the rest
of the list |ps|).  If the match succeeds, the right-hand side is
evaluated and returned as the result of the application.  If it fails,
the next equation is tried, and if all equations fail, an error
results.  All of the equations that define a particular function must
appear together, one after the other.

Defining functions by pattern matching is quite common in Haskell, and
you should eventually become familiar with the various kinds of
patterns that are allowed; see Appendix \ref{ch:patterns} for a
concise summary.}  \index{pattern}

%% This is called a \emph{recursive} function definition since |hList|
%% ``refers to itself'' on the right-hand side of the second equation.

Given this definition of |hList| the definition of |mel| can be
rewritten as:
\begin{spec}
mel = hList qn [p1, p2, p3]
\end{spec}

We can prove that this definition is equivalent to the old via
calculation:
\begin{spec}
mel = hList qn [p1, p2, p3]
==> hList qn (p1:p2:p3:[])
==> hNote qn p1 :+: hList qn (p2:p3:[])
==> hNote qn p1 :+: hNote qn p2 :+: hList qn (p3:[])
==> hNote qn p1 :+: hNote qn p2 :+: hNote qn p3 :+: hList qn []
==> hNote qn p1 :+: hNote qn p2 :+: hNote qn p3 :+: rest 0
\end{spec}
The first step above is not really a calculation, but rather a
rewriting of the list syntax.  The remaining calculations each
represent an unfolding of |hList|. 
\index{abstraction!data||)}
\index{abstraction||)}

Lists are perhaps the most commonly used data structure in Haskell,
and there is a rich library of functions that operate on them.  In
subsequent chapters lists will be used in a variety of interesting
computer music applications.

\vspace{.1in}\hrule

\begin{exercise}{\em
Modify the definitions of |hNote| and |hList| so that they each take
an extra argument that specifies the interval of harmonization (rather
than being fixed at -3).  Rewrite the definition of |mel| to take these
changes into account.}
\end{exercise}

\vspace{.1in}\hrule

\section{Haskell Equality vs.\ Euterpean Equality}

The astute reader will have objected to the proof just completed,
arguing that the original version of |mel|:
\begin{spec}
hNote qn p1 :+: hNote qn p2 :+: hNote qn p3
\end{spec}
is not the same as the terminus of the above proof:
\begin{spec}
hNote qn p1 :+: hNote qn p2 :+: hNote qn p3 :+: rest 0
\end{spec}
Indeed, that reader would be right!  As Haskell values, these
expressions are \emph{not} equal, and if you printed each of them you
would get different results.  So what happened?  Did proof by
calculation fail?

No, proof by calculation did not fail, since, as just pointed out,
as Haskell values these two expressions are not the same, and proof by
calculation is based on the equality of Haskell values.  The problem
is that a ``deeper'' notion of equivalence is needed, one based on the
notion of \emph{musical} equality.  Adding a rest of zero duration to
the beginning or end of any piece of music should not change what we
\emph{hear}, and therefore it seems that the above two expressions are
\emph{musically} equivalent.  But it is unreasonable to expect Haskell
to figure this out for the programmer!

As an analogy, consider the use of an ordered list to represent a set
(which is unordered).  The Haskell values |[x1,x2]| and |[x2,x1]| are
not equal, yet in a program that ``interprets'' them as sets, they
\emph{are} equal.

The way this problem is approached in Euterpea is to formally define a
notion of \emph{musical interpretation}, from which the notion
of \emph{musical equivalence} is defined.  This leads to a kind of
``algebra of music'' that includes, among others, the following axiom:
\begin{spec}
m :+: rest 0 === m
\end{spec}
The operator |(===)| should be read, ``is musically equivalent to.''
With this axiom it is easy to see that the original two expressions
above \emph{are} in fact musically equivalent.

For a more extreme example of this idea, and to entice the reader to
learn more about musical equivalence in later chapters, note that
|mel|, given pitches |p1 = Ef|, |p2 = F|, |p3 = G|, and duration |d =
1/4|, generates the harmonized melody shown in Figure \ref{fig:mel};
we can write this concretely in Euterpea as:
\begin{spec}
mel1 =  (note (1/4) (Ef,  4) :=: note (1/4) (C,4)) !:+:
        (note (1/4) (F,   4) :=: note (1/4) (D,4)) !:+:
        (note (1/4) (G,   4) :=: note (1/4) (E,4))
\end{spec}
The definition of |mel1| can then be seen as a \emph{polyphonic}
interpretation of the musical phrase in Figure \ref{fig:mel}, where
each pair of notes is seen as a harmonic unit.  In contrast, a
\emph{contrapuntal} interpretation sees two independent \emph{lines},
or \emph{voices}, in this case the line $\langle$E$\flat$,F,G$\rangle$
and the line $\langle$C,D,E$\rangle$.  In Euterpea we can write this
as:
\begin{spec}
mel2 =  (note (1/4) (Ef,  4) :+: note (1/4) (F,4)   :+: note (1/4) (G,4))
        :=:
        (note (1/4) (C,   4) :+: note (1/4) (D,4)   :+: note (1/4) (E,4))
\end{spec}
|mel1| and |mel2| are clearly not equal as Haskell values.  Yet if
they are played, they will \emph{sound} the same---they are, in the
sense described earlier, \emph{musically equivalent}.  But proving
these two phrases musically equivalent will require far more than a
simple axiom involving |rest 0|.  In fact this can be done in an
elegant way, using the algebra of music developed in Chapter
\ref{ch:algebra}.

\begin{figure*}
%% \includegraphics{pics/threenoteharm.pdf}
\centerline{
\epsfysize=0.6in 
\epsfbox{pics/threenoteharm.eps}
}
\caption{Polyphonic vs.\ Contrapuntal Interpretation}
\label{fig:mel}
\end{figure*}

\section{Code Reuse and Modularity}
\label{sec:code-reuse}

There does not seem to be much repetition in the last definition of
|hList|, so perhaps the end of the abstraction process has been
reached.  In fact, it is worth considering how much progress has been
made.  The original definition:
\begin{spec}
mel =  (note qn p1 :=: note qn (trans (-3) p1)) !:+: 
       (note qn p2 :=: note qn (trans (-3) p2)) !:+: 
       (note qn p3 :=: note qn (trans (-3) p3))
\end{spec}
was replaced with:
\begin{spec}
mel = hList qn [p1, p2, p3]
\end{spec}
But additionally, definitions for the auxiliary functions |hNote| and
|hList| were introduced:
\begin{spec}
hNote      :: Dur -> Pitch -> Music Pitch
hNote d p  = note d p :=: note d (trans (-3) p)

hList           :: Dur -> [Pitch] -> Music Pitch
hList d []      = rest 0
hList d (p:ps)  = hNote d p :+: hList d ps
\end{spec}
In terms of code size, the final program is actually larger than the
original!  So has the program improved in any way?

Things have certainly gotten better from the standpoint of ``removing
repeating patterns,'' and we could argue that the resulting program
therefore is easier to understand.  But there is more.  Now that
auxiliary functions such as |hNote| and |hList| have been defined, we
can \emph{reuse} them in other contexts.  Being able to reuse code is
also called \emph{\indexwd{modularity}}, since the reused components
are like little modules, or building blocks, that can form the
foundation of many applications.\footnote{``Code reuse'' and
  ``modularity'' are important software engineering principles.}  In a
later chapter, techniques will be introduced---most notably,
\emph{higher-order functions} and \emph{polymorphism}---for improving
the modularity of this example even more, and substantially increasing
the ability to reuse code.

\section{[Advanced] Programming with Numbers}
\label{sec:numbers-caveat}
\index{number systems||(}

In computer music programming, it is often necessary to program with
numbers.  For example, it is often convenient to represent pitch on a
simple absolute scale using integer values.  And when computing with
analog signals that represent a particular sound wave, it is necessary
to use floating point numbers as an approximation to the reals.  So it
is a good idea to understand precisely how numbers are represented
inside a computer, and within a particular language such as Haskell.

In mathematics there are many different kinds of number systems.  For
example, there are integers, natural numbers (i.e.\ non-negative
integers), real numbers, rational numbers, and complex numbers.  These
number systems possess many useful properties, such as the fact that
multiplication and addition are commutative, and that multiplication
distributes over addition.  You have undoubtedly learned many of these
properties in your studies, and have used them often in algebra,
geometry, trigonometry, physics, and so on.

Unfortunately, each of these number systems places great demands on
computer systems.  In particular, a number can in general require an
\emph{arbitrary amount of memory} to represent it.  Clearly, for
example, an irrational number such as $\pi$ cannot be represented
exactly; the best we can do is approximate it, or possibly write a
program that computes it to whatever (finite) precision is needed in a
given application.  But even integers (and therefore rational numbers)
present problems, since any given integer can be arbitrarily large.

Most programming languages do not deal with these problems very well.
In fact, most programming languages do not have exact forms of many of
these number systems.  Haskell does slightly better than most, in that
it has exact forms of integers (the type \indexwdhs{Integer}) as well
as rational numbers (the type \indexwdhs{Rational}, defined in the
Ratio Library).  But in Haskell and most other languages there is no
exact form of real numbers, for example, which are instead
approximated by \emph{floating-point numbers} with either single-word
precision (\indexwdhs{Float} in Haskell) or double-word precision
(\indexwdhs{Double}).  Even worse, the behavior of arithmetic
operations on floating-point numbers can vary somewhat depending on
what kind of computer is being used, although hardware standardization
in recent years has reduced the degree of this problem.

The bottom line is that, as simple as they may seem, great care must
be taken when programming with numbers.  Many computer errors, some
quite serious and renowned, were rooted in numerical incongruities.
The field of mathematics known as \emph{ \indexwd{numerical analysis}} is
concerned precisely with these problems, and programming with
floating-point numbers in sophisticated applications often requires a
good understanding of numerical analysis to devise proper algorithms
and write correct programs.

As a simple example of this problem, consider the distributive law,
expressed here as a calculation in Haskell, and used earlier in
this chapter in calculations involving the function |simple|:
\begin{spec}
a*(b+c) ==> a*b + a*c
\end{spec}
For most floating-point numbers, this law is perfectly valid.  For
example, in the GHC implementation of Haskell, the expressions
|pi*(3+4) :: Float| and |pi*3+pi*4 :: Float| both yield the same
result: 21.99115.  But funny things can happen when the magnitude of
|b+c| differs significantly from the magnitude of either |b| or
|c|.  For example, the following two calculations are from GHC:
\begin{spec}
5*(-0.123456  +    0.123457)  :: Float ==> 4.991889e-6
5*(-0.123456) + 5*(0.123457)  :: Float ==> 5.00679e-6
\end{spec}
Although the discrepancy here is small, its very existence is
worrisome, and in certain situations it could be disastrous.  The
precise behavior of floating-point numbers will not be discussed
further in this textbook.  Just remember that they are
\emph{approximations} to the real numbers.  If real-number accuracy is
important to your application, further study of the nature of
floating-point numbers is probably warranted.

On the other hand, the distributive law (and many others) is valid in
Haskell for the exact data types |Integer| and |Ratio Integer|
(i.e.\ rationals).  Although the representation of an |Integer| in
Haskell is not normally something to be concerned about, it should be
clear that the representation must be allowed to grow to an arbitrary
size.  For example, Haskell has no problem with the following number:
\begin{spec}
veryBigNumber  :: Integer
veryBigNumber  = 43208345720348593219876512372134059
\end{spec}
and such numbers can be added, multiplied, etc.\ without any loss of
accuracy.  However, such numbers cannot fit into a single word of
computer memory, most of which are limited to 32 or 64 bits.  Worse,
since the computer system does not know ahead of time exactly how many
words will be required, it must devise a dynamic scheme to allow just
the right number of words to be used in each case.  The overhead of
implementing this idea unfortunately causes programs to run slower.

For this reason, Haskell (and most other languages) provides another
integer data type called \indexwdhs{Int} that has maximum and minimum
values that depend on the word-size of the particular computer being
used.  In other words, every value of type |Int| fits into one word of
memory, and the primitive machine instructions for binary numbers can
be used to manipulate them efficiently.\footnote{The Haskell Report
  requires that every implementation support |Int|s at least in the
  range $-2^{29}$ to $2^{29}-1$, inclusive.  The GHC implementation
  running on a 32-bit processor, for example, supports the range
  $-2^{31}$ to $2^{31}-1$.}  Unfortunately, this means that
\emph{overflow} or \emph{underflow} errors could occur when an |Int|
value exceeds either the maximum or minimum values.  Sadly, most
implementations of Haskell (as well as most other languages) do not
tell you when this happens.  For example, in GHC running on a 32-bit
processor, the following |Int| value:
\begin{spec}
i  :: Int
i  = 1234567890
\end{spec}
works just fine, but if you multiply it by two, GHC returns the value
|-1825831516|!  This is because twice |i| exceeds the maximum allowed
value, so the resulting bits become nonsensical,\footnote{Actually,
  these bits are perfectly sensible in the following way: the 32-bit
  binary representation of |i| is 01001001100101100000001011010010,
  and twice that is 10010011001011000000010110100100.  But the latter
  number is seen as negative because the 32nd bit (the highest-order
  bit on the CPU on which this was run) is a one, which means it is a
  negative number in ``twos-complement'' representation.  The
  twos-complement of this number is in turn
  01101100110100111111101001011100, whose decimal representation is
  1825831516.} and are interpreted in this case as a negative number
of the given magnitude.

This is alarming!  Indeed, why should anyone ever use |Int| when
|Integer| is available?  The answer, as implied earlier, is
efficiency, but clearly care should be taken when making this choice.
If you are indexing into a list, for example, and you are confident
that you are not performing index calculations that might result in
the above kind of error, then |Int| should work just fine, since a
list longer than $2^{31}$ will not fit into memory anyway!  But if you
are calculating the number of microseconds in some large time
interval, or counting the number of people living on earth, then
|Integer| would most likely be a better choice.  Choose your number
data types wisely!

In this textbook the numeric data types |Integer|, |Int|, |Float|,
|Double|, |Rational|, and |Complex| will be  used for a variety of
different applications; for a discussion of the other number types,
consult the Haskell Report.  As these data types are used, there will
be little discussion about their properties---this is not, after all,
a book on numerical analysis---but a warning will be cast whenever
reasoning about, for example, floating-point numbers, in a way that
might not be technically sound.  \index{number systems||)}

%% ---

\out{
\section{Qualified Types}
\label{sec:qualified-types}

A polymorphic type such as |(a->a)| can be viewed as shorthand for
$\forall($|a|$)|a->a|$, which can be read ``\emph{for all} types |a|,
functions mapping elements of type |a| to elements of type |a|.''
Note the emphasis on ``\emph{for all}.''

In practice, however, there are times when we would prefer to limit a
polymorphic type to a smaller number of possibilities.  A good example
is a function such as |(+)|.  It is probably not a good idea to limit
|(+)| to a \emph{single} (that is, \emph{monomorphic}) type such as
|Integer->Integer->Integer|, since there are other kinds of
numbers---such as rational and floating-point numbers---that we would
like to perform addition on as well.  Nor is it a good idea to have a
different addition function for each type of number that we wish to
add, since that would require giving each a different name, such as
|addInteger|, |addRational|, |addFloat|, etc.  And, unfortunately,
giving |(+)| a type such as |a->a->a| will not work, since this would
imply that we could add things other than numbers, such as
characters, pitch classes, lists, tuples, functions, and any type that
you might define on your own!

\index{type!qualified} \index{class} 

Haskell provides a solution to this problem through the use of {\em
  qualified types}.  Conceptually, it is helpful to think of a
qualified type just as a polymorphic type, except that in place of
``\emph{for all} types |a|'' it will be possible to say ``for all
types |a| \emph{that are members of the type class} |C|,'' where the
type class |C| can be thought of as a set of types.  For example,
suppose there is a type class \indexwdhs{Num} with members |Integer|,
|Rational|, and |Float|.  Then an accurate type for |(+)| is
$\forall($|a|$\in$|Num|$)$|a -> a -> a|.  But in Haskell, instead of
writing $\forall(|a|\in|Num|)\cdots$, the notation |Num a =>|$\cdots$
is used.  So the proper type signature for |(+)| is:
\begin{spec}
(+) :: Num a => a -> a -> a
\end{spec}
which should be read: ``for all types |a| that are members of the type
class |Num|, |(+)| has type |a -> a -> a|.''  Members of a type class
are also called \emph{instances} of the class, and these two terms
will be used interchangeably in the remainder of the text.  The |Num a
=>|$\cdots$ part of the type signature is often called a
\emph{context}, or \emph{constraint}.

\index{class}
\syn{It is important not to confuse |Num| with a data type or a
constructor within a data type, even though the same syntax 
(``|Num a|'') is used.  |Num| is a \emph{type class}, and the
context of its use (namely, to the left of a |=>|) is always
sufficient to determine this fact.}

\begin{figure}
\begin{tabular}{||||l||l||l||||} \hline
{\bf Type}  & {\bf Key} & {\bf Key} \\
{\bf Class} & {\bf functions} & {\bf instances} \\
\hline
|Num|  & |(+),(-),(*) :: Num a => a->a->a| & |Integer, Int, Float, Double,| \\ 
       & |negate :: Num a => a->a|         & |Rational| \\

\hline
|Eq|   & |(==),(/=) :: Eq a => a->a->Bool| & |Integer, Int, Float, Double,| \\
&&                                           |Rational, Char, Bool, ... | \\
\hline
|Ord|  & |(>),(<),(>=),(<=) ::|            & |Integer, Int, Float, Double,| \\
       & \ \ \ \ |Ord a => a->a->Bool|     & |Rational, Char, Bool, ... | \\
       & |max,min :: Ord a => a->a->Bool|  & \\
\hline
|Enum| & |succ,pred :: Enum a => a->a|     & |Integer, Int, Float, Double,| \\
       & also enables arithmetic sequences & |Rational, Char, Bool, ... | \\
\hline
|Show| & |show :: Show a => a -> String|   & Almost every type except \\
       &                                   & for functions \\
\hline
|Read| & |read :: Read a => String -> a|   & Almost every type except \\
       &                                   & for functions \\
\hline
\end{tabular}
\caption{Common Type Classes and Their Instances}
\label{fig:common-type-classes}
\end{figure}

Recall now the type signature previously given for |simple|:
\begin{spec}
simple         :: Integer -> Integer -> Integer -> Integer
simple x y z   = x*(y+z)
\end{spec}
Note that |simple| uses the operator |(+)| discussed above.  It also
uses |(*)|, whose type is the same as that for |(+)|:
\begin{spec}
(*) :: Num a => a -> a -> a
\end{spec}
This suggests that a more general type for |simple| is:
\begin{spec}
simple         :: Num a => a -> a -> a -> a
simple x y z   = x*(y+z)
\end{spec}
Indeed, this is the preferred, most general type that can be given for
|simple|.  It can now be used with any type that is a member of the
|Num| class, which includes |Integer|, |Int|, |Rational|, |Float| and
|Double|, among others.

The ability to qualify polymorphic types is a unique feature of
Haskell, and, as you will soon see, provides great expressiveness.  In
particular, you will see that it is possible to define your own type
class and its members.  For now, all you need to know is that some
functions and operators are predefined to be instances of certain
type classes, such as |(+)| and |(*)| above.  Table
\ref{fig:common-type-classes} shows a number of others.  For example,
the |Show| class allows us to convert values to strings:
\begin{spec}
show D               ==> "D"
show concertA        ==> "(A,4)"
show (simple 3 9 5)  ==> "42"
\end{spec}
The |Read| class allows us to go the other way around:
\begin{spec}
read "D"             ==> D
read "(A,4)"         ==> (A,4)
read "42"            ==> 42
\end{spec}
The |Eq| class allows testing values for equality:
\begin{spec}
simple 3 9 5 == 42   ==> True
concertA == (A,5)    ==> False
\end{spec}
And the |Ord| class has relational operators for types whose values
can be ordered:
\begin{spec}
simple 3 9 5 > 41    ==> True
max 42 27            ==> 42
'a' < 'b'            ==> True
\end{spec}
The |Enum| class allows us to use \emph{arithmetic sequences}, which
will be explained in a later chapter.
}