Answers updated for 2010
Why introduce both Dr Scheme and Chez Scheme in
this course?
What is the difference between proper and improper
lists?
What is an interpreter?
What is the difference between y and 'y?
How can I cope with all of these parentheses?
How does that (apply apply (list procedure? ... thing on page 22 of EPL work?
What is a predicate? Where does the name
"predicate" come from?
What is the difference between a function and a procedure?
Is (lambda (x) (+ x
5)) a procedure?
Why introduce both Dr Scheme and Chez
Scheme in this course?
It's kind of like the way we introduce both Idle and Eclipse in CSSE 120
for writing Python programs. The
Dr. Scheme environment is easy to learn, so you can concentrate at the
beginning on learning Scheme itself.
It is also a great place to bring up a shell for a quick experiment with
a new (to you) Scheme concept.
I prefer Chez Scheme (from within Emacs) for general development purposes; your mileage may vary.
Chez Scheme is more full-featured,
and made it easier to write the Scheme grading program that we will use. Thus, when your code is graded, it wil be run through Chez
Scheme. That should not make a
difference in the early assignments; it may make a difference when we
do assignments that use define-datatype
later in the course. I
recommend that you get into the habit of testing your code in Chez Scheme before you submit it to the
grading program.
What is the difference between proper and
improper lists?
A proper list is the same kind of list that you saw in Data Structures.
Each node (in Scheme, this is known as a "pair" or "cons
cell") contains two parts, the data (car) and a
pointer to the next node (cdr).
The cdr of the last node in
a proper list is null. The external representation of a list is simply a
parenthesized collection of elements, such as (a
b c d e f g).
There is nothing to prevent you from putting something other than a null
pointer in the cdr
of last node; if you do so, you get an improper list. For example, in (a b . c),
there are two nodes. The first node contains a in its car,
and a pointer to the second node in its cdr. The second node contains b
and c. In the early part of this
course, we will almost always use proper lists.
What is an interpreter?
An interpreter is simply a program that reads instructions in some
programming language and "executes" them. A good example is a typical
microprocessor. It reads a program in that processor's machine language and
executes it. An interpreter for a high level language does a similar thing, but
it uses software, not just hardware, to do the interpretation. A compiler
usually translates a high-level language source file into a machine language
object file which can be interpreted by the hardware. A Java compiler
translates Java source code into Java Byte Code, which can then be interpreted
by the Java Virtual Machine. Many Scheme interpreters (including Chez
Scheme, but not Petite Chez scheme) compile source code into byte code
before executing it, and have a facility for saving the compiled code so that
it will load faster next time.
What is the difference between y and
'y?
Both involve the symbol y.
When used by itself, y stands
for the value of the variable named y,
and causes the Scheme interpreter to look up the current value of this
variable. The quote prevents the evaluation, and 'y just stands for the symbol y itself. In Scheme, as in
Maple, it is possible to do purely symbolic computations, so there needs to be
a way to represent an unevaluated symbol. Scheme's way is to quote it. Note
that 'y is an abbreviation for (quote
y)
How can I cope with all of these parentheses?
Like in any programming language, breaking lines at reasonable places and
using a reasonable, consistent indentation scheme (no pun intended) can help a
lot. Emacs (and Dr. Scheme) can also help:
Esc ctrl-f moves the cursor to
the end of the next (sub)expression.
Esc ctrl-b moves the cursor to
the beginning of the previous (sub)expression.
Esc ctrl-k deletes the next
(sub) expression and places it in the kill ring (so it can be pasted in
somewhere else via ctrl-y). When
you type a closing paren (or closing brace or
bracket), emacs temporarily blinks the matching
opening symbol. Mainly, you'll just need a couple of weeks of using Scheme, and
you'll get used to the parentheses.
How does that (apply apply (list procedure? ... thing on page 22 of EOPL-1 work? This question has been asked before. A few years ago, I attempted to write a detailed explanation. Even with the explanation, I admit that this example is a bit heavy for a Scheme beginner. See: apply.html .
What is a predicate? Where does the name
"predicate" come from?
A predicate is any procedure that returns a true or false value. You can
recognize a built-in Scheme predicate because its name (almost always) ends in
a question mark (an exception is =). You should give similar names to
predicates that you write (such as divisible-by7?).
The name comes from mathematical logic. My Webster's New World College
Dictionary gives this definition for predicate :
"something that is affirmed or denied about the subject of a
proposition." Thus the application (integer?
x) is used to affirm or deny that the variable x currently contains an integer value.
What is the difference between a function and a
procedure?
The generic CS lingo is that functions return values, while procedures
don't return anything. Java metalanguage uses the word "method" for
both, and C uses "function" for both.
Some languages, such as Pascal,
In C they are all called functions
but some are used as procedures; in
Scheme they are all called
procedures but most are used as
functions. From now on in our discussion of Scheme, I will mean the same thing
when I say "function" as when I say "procedure".
Is (lambda (x) (+
x 5))
a procedure?
Not exactly. (lambda (x) (+ x 5)) is a piece of Scheme code.
When the interpreter evaluates this code, it builds a data structure that
represents an "add 5" procedure (Later we will call such a data
structure a closure. So strictly speaking a procedure is a Scheme
internal thing, while a lambda expression is source code. When the context does
not allow for easy confusion, however, it is often convenient to refer to the lambda
expression itself as a procedure.
When we are writing a Scheme interpreter, it will be very important to distinguaish between the code (lambda expression) and the
procedure (an internal data structure of our interpreter) that is created when
we evaluate that code.