ArsDigita University, Structure and Interpretation of Computer Programs
Lecture Notes for Lecture 1 -- 1 October 2000
Topics covered in today's lecture:
This course is the first programming course at ADU, taught in Scheme.
Scheme is a useful language for an intro class because we can teach
you about its syntax in a very short time (in fact, in this lecture
alone) and you can start writing programs immediately. Scheme allows
us to focus on concepts rather than syntax.
Looking at the upcoming courses at ADU, here are some ways that the
material in this class applies to the upcoming courses:
Additionally, we'll touch on compilers in this course. Compilers are
not in the ADU curriculum, but it's good to understand how one might
write a compiler.
Every powerful language has
- Discrete Math: Shai plans to use Scheme for a problem set on RSA
- How Computers Work: register machines in this course will be seen
- Object-Oriented Programming: you'll see object-oriented concepts
introduced in this class
- Algorithms: we'll cover some basic analysis of algorithms in
terms of space and time. You'll also be designing algorithms to
complete the problem sets.
- Banzai AI: will either use Scheme or CommonLISP (similar to
- primitive expressions: the simplest entities, such as 3 and +
- means of combination: buidling compound elements from simpler
ones such as (+ 3 4)
- means of abstraction: a way for naming compound elements and then
manipulating them as units such as (define square (lambda (x) (* x x)))
Scheme does the following three things:
- Reads an expression
- Evaluates it to produce a value
- Prints the value
The returned value has a small set of types, including number, boolean
and procedure. (Later, we'll see symbol, pair, vector, and promise (stream).)
There are 4 types of expressions:
- Constants: numbers, booleans. Examples: 4 3.141592 #t #f
- Variables: names for values. We create these using the special
- Special forms: have special rules for evaluation. In addition,
you may not redefine a special form.
- Combinations: (<operator> <operands>). These are sometimes
called "function calls" or "procedure applications."
The first two types of expressions (constants and variables) are
primitive expressions -- they have no parentheses. The second two
types are called compound expressions -- they have parentheses.
- Every expression has a value (except for errors, infinite loops
and the define special form)
- To find the value of a combination,
- Find values of all subexpressions in any order
- Apply the value of the first to the values of the rest
- The value of a lambda expression is a procedure
When you hear the words "write a procedure," you should think of
lambda. Lambda is a special form that creates a procedure.
There are three parts to the lambda expression:
For example, let's write a procedure to square a number:
- parameter list
(lambda (x) (* x x))
How do we use this procedure that we just wrote? Well, we can
- (x) is the parameter list. In this case, we only have one
- (* x x) is the body of the lambda. The body of the
lambda will not be evaluated until the procedure is applied.
((lambda (x) (* x x)) 3)
This will return 9.
If we want to square 9, we can write
((lambda (x) (* x x)) 9)
But we don't want to have to keep typing the procedure over and
over. This leads us to another special form: define.
Define is a special form that allows us to name
objects. Define has three parts:
Here are some examples:
- the object you want the name to be bound to
(define pi 3.141592)
(define four 8)
We can use define to name our procedure we wrote above to allow
us to use it without having to retype the lambda expression over and
(define square (lambda (x) (* x x)))
Recall that special forms are those expressions that begin with an
open parenthesis followed by one of the 15 "magic words":
and, begin, case, cond, define, do, if, lambda, let, let*, letrec,
or, quasiquote, quote, set!
Special forms have special rules for their evaluation. Recall from
the mantras that to find the value of a combination, you find the
values of all of the subexpressions in any order. With special forms,
this is not done. The order of the evaluation of the subexpressions
is specified for each special form.
(and <exp1> <exp2> ...)
And evaluates the expressions one at a time in left to right order.
As soon as one of the expressions evaluates to #f (false), the value
of the and expression is #f (false) and none of the remaining
expressions are evaluated.
(or <exp1> <exp2> ...)
Or evaluates the expressions one at a time in left to right order. As
soon as one of the expressions evaluates to #t (true), the value of
the or expression is #t (true) and none of the remaining expressions
(if <predicate> <consequent> <alternative>)
The predicate is evaluated. If it is true, the value of the
consequent will be returned. If it is false, the value of the
alternative will be returned. In this special form, never will the
consequent and alternative both be evaluated.
(cond (<pred1> <exp1>)
The first predicate is evaluated. If it is true, the value of the
first expression will be returned. If it is false, the second
predicate will be evaluated. The computer will continue to evaluate
the predicates until one is true. The value of the expression
corresponding to the true predicate will be returned. Note that the
else will always be true.
Written by: Holly Yanco
Last update: 1 October 2000