Our main objectives in this course are to learn about algorithms -- step-by-step methods for solving problems -- and to learn how to direct computers to perform such algorithms for us. A programming language, such as Scheme, is a formal notation in which one can express algorithms so exactly that a computer can perform them without any other assistance from human beings. The expression of an algorithm in such a notation is called a program, and the computer is said to be executing the program when it is performing the algorithm as directed.
Let's start with a very short Scheme program that directs the computer to find the answer to the question ``What is the square root of 137641?'' Here it is:
(sqrt 137641)
When this program is executed, the computer's central processing unit -- the electronic circuit that directs the movement and transformation of data inside the computer -- calculates the square root, and the DrScheme software takes the result of the calculation and displays it in the Interactions window:
371
When the central processor calculates a square root, it breaks the
computation down into a large number of much simpler steps. Some
programmers who are experts on square roots and on the idiosyncracies of
the Intel Pentium processor figured out and wrote down a step-by-step
method for computing the square root of any number, using only the very
elementary transformations that the processor can perform. DrScheme
recognizes sqrt as the name of this algorithm and knows where
the processor instructions that carry it out are stored. When DrScheme
receives a command to compute a square root, it recovers these instructions
and arranges for the processor to follow them.
Although it would be interesting and instructive to examine the method by
which the processor calculates square roots, at this stage it will be more
convenient for us to think of sqrt as a primitive
procedure, regarding the calculation of a square root as a single step
that is usually just part of a much larger program. The idea that a
computation can be regarded as a complicated sequence of instructions on
one level, and as a unit on another, more abstract level is very common in
computer science.
A program written in Scheme has a particularly simple structure: it is a
sequence of definitions and commands -- any number of them, in any order.
DrScheme reacts to each definition in a program by memorizing it, and to
each command by carrying out the command and displaying any results that it
produces. The expression (sqrt 137641) is a command -- ``Compute
the square root of 137641!'' -- and it produces one result, which is duly
displayed.
The full Scheme language that DrScheme supports contains several hundred primitive procedures -- operations, such as finding the square root of a number, for which DrScheme can use pre-packaged algorithms.
A procedure call is a command that directs DrScheme to activate
a procedure such as sqrt. (Note that `sqrt' is the name of
the procedure, and `(sqrt 137641)' is the procedure call.) In
Scheme, every procedure call begins with a left parenthesis and ends with
the matching right parenthesis. Within the parentheses, one always begins
by identifying the procedure to be called and then continues by identifying
the arguments -- the values that the procedure is supposed to
operate on. The sqrt procedure takes only one argument -- the
number of which you want the square root -- but other procedures take two
or more arguments, and some need no arguments at all.
All arithmetic in Scheme is done with procedure calls. The primitive
procedure + adds numbers together; the primitive procedure -
subtracts one number from another. Similarly, the primitive procedure
* performs multiplication, and the primitive procedure /
performs division. The fact that in a procedure call the procedure is
identified first makes calls to these procedures look different from
ordinary arithmetic expressions. For instance, to tell DrScheme to
subtract 68343 from 81722, one gives the command
(- 81722 68343)
If this command is the whole program, running it causes DrScheme to display the result:
13379
DrScheme learns new names for things by reading definitions. Here's what a definition looks like:
(define days-in-a-week 7)
Like a procedure call, a definition begins and ends with matching
parentheses. To distinguish between definitions and procedure calls,
DrScheme looks at what comes immediately after the left parenthesis. In a
definition, the keyword define must appear at that point. Define is not the name of a procedure; it is a keyword,
constituting part of the syntax of the Scheme programming language. Its
only role is to serve as the mark of a definition.
After the keyword define, a definition contains the name being
defined and an expression that identifies the value that the name should
stand for. In this example, the name is days-in-a-week. (In
Scheme, a name can contain hyphens internally.) The value that it names is
the number 7. Once DrScheme has seen this definition, it remembers that
days-in-a-week stands for 7.
For example, here is a Scheme program that begins with the definition shown above, and continues with a command that uses the name that the definition introduces:
(define days-in-a-week 7) (* days-in-a-week 52)
When this program is executed, DrScheme displays the result of the computation that the command directs it to perform:
364
Since the value associated with the name days-in-the-week is
7, and the result of multiplying 7 by 52 is 364, this result is correct.
The value that gets a new name need not be a number; it can be anything,
even a procedure. For example, if you don't like the name *
for the multiplication procedure and would rather call it by the name
multiply, you can just start each program with the definition
(define multiply *)
At this point, I hope you're wondering what other useful and interesting procedures are built into Scheme. Section 6.2.5 of the Revised5 report on the algorithmic language Scheme contains a list of the ones that are mainly about numbers, and that's only one section of the full roster of standard Scheme procedures. Fortunately, most of the primitive procedures perform small, simple jobs and are easily learned.