Programming Languages (CS302 2006S)

Notes on Chapters 1-6 of R5RS

Comments on:

Kelsey, R., Clinger, W., and Rees, J. (Eds). (1998). Revised5 Report on the Algorithmic Language Scheme.

Comments from: Michael Claveria (*), Davis Hart, Alex Leach, Angeline Namai, Mark Nettling, Dave Ventresca.

No Comments from: Peter Brown (x), Brad Miller (x), Dimitar Tasev (x).


It was painful enough to go through Scheme once. This lovely documentation of its procedures was much like reading the Java APIs, though these explain things in more detail. Basically, it would be more helpful if I was looking for something in particular instead of just reading it generally (because I cannot remember all those details, which is why this sort of documentation exists).

Sometimes I want you to just read and see what you find. As you see from the subsequent comments, your colleagues have found many surprising or questionable ideas in the report.

Though the reading was long, it was good to read as a reaffirmation of what we know about Scheme. I was certainly not aware of all the equivalent ways of representing data, (e.g. reals especially). For some reason I have been unclear as to the exact definition of a tail-recursive procedure, this reading made it quite clear to me, so that's another good thing. I had never seen the let-syntax and letrec-syntax expressions before, so reading about those was informative. Section 4 (other than the parts about macros, the let-syntax, letrec-syntax and syntax-rules (which I'm still unsure about, if you could go over an example in class; that would be helpful)) was not as valuable to me personally because the information contained therein I would hope is fairly common knowledge. Sections 5 and 6 I felt comfortable with.

We'll spend a day on macros later this semester.

I don't fully understand the Let-syntax and letrec-syntax probably because I'm not sure about the concept of binding syntactic keywords to macro transformers. Is this associating a macro with some keyword?

Yes, essentially.

Most of the reading was pretty clear, I think except for some of the concepts in the later parts of chapter 6. On page 35,

(eval '(* 7 3) (scheme-report-environment 5))

returns the value 21. What does setting scheme-report-environment to 5 do? What are the values supported by the implementation of scheme-report-environment and null-environment?

We don't set scheme-report-environment to 5, we present 5 as a parameter (thereby asking for the environment described in R5RS). Different imPlementations support different environments. DrScheme seems to support only 5.

What's the point of delaying the evaluation of an expression?

Can you explain the idea behind the force procedure in scheme?

Scheme, like most languages, evaluates is arguments eagerly. That is, you evaluate the arguments to a procedure before applying that procedure. Some languages take an alternate view, and delay the evaluation of arguments until they are needed. For example, if we define a constant-one procedure that just returns 1, then it seems silly to evaluate the parameter during a call. Scheme lets you use delay and force to make that choice.

The sections defining some of the features of Scheme, such as continuations, internal object representation, and macros, were quite interesting. However, the document ultimately led to many unanswered questions. Scheme's equivalence procedures are quite confusing. I wonder what is the rational for multiple procedures to determine equality or equivalence. I believe it would be simpler to define one equals function, or one for each type. The programmer should use transformation procedures if he or she wishes to compare objects which might be equal in, for example, printable form but not in internal representation.

Believe it or not, but the various equivalence procedures are designed to permit the programmer to choose the appropriate level of efficiency. In some cases, all you care about is do these things share the same memory location, in which case you don't want the predicate to do anything complicated. In others, you're willing to sacrifice some running time for a richer meaning of equality.

As for the section on equivalence predicates, why does (eqv? (cons 1 2) (cons 1 2)) return false, yet both arguments are pairs composed of the same values? The authors mention that eqv? returns true only if the pairs denote the same locations, but clearly I do not understand this condition.

The eqv? procedure looks only at memory locations. Each call to cons allocates a separate location.

What is the deal with macros?

Some Schemers and Lisper (Graham is a notable example) firmly believe that one of the great benefits of Scheme and Lisp are that you can change the syntax if you wish. Macros support that kind of redefinition. A rich macro language is particularly necessary if you want to permit your programmers to write macros equivalent in power to things like delay or the short-circuit and and or.

Calling parameters objects also seems to be a stretch too, given that it is not an object-oriented language.

also ... too seems a bit redundant. On a more serious note, different folks have different senses of what an object is.

After reading the R5RS, some of the derived expression types (4.2) still don't seem to have clear application to me, specifically delayed evaluation and quasiquotation. Also, what is the "desired structure" in Quasiquotation (4.2.6)?

You want to build an S-expression. You know the form of the S-expression (nesting, number of elements at each level, etc). However, at different times, you want to fill in different values. Quasiquotation is intended to permit you to do just that without annoying list and cons commands. I'm not a big fan of such syntactic sugar, but I'm in the minority.

The concluding sentences of the and and or paragraphs in section 4.2.1 are somewhat puzzling. How is it possible for the and-conditional to be vacuously true while the or-conditional is vacuously false? Isn't or weaker than and, so that whenever and returns true, or automatically returns true when applied to the same case?

My understanding is that they chose these definitions to make the recursive expression of these procedures clearer. Approximately,

(define and
  (lambda l
    (cond 
      ((null? l) #t)
      ((car l) (apply and (cdr l)))
      (else #f))))

Disclaimer: I usually create these pages on the fly, which means that I rarely proofread them and they may contain bad grammar and incorrect details. It also means that I tend to update them regularly (see the history for more details). Feel free to contact me with any suggestions for changes.

This document was generated by Siteweaver on Wed May 10 09:03:19 2006.
The source to the document was last modified on Wed Feb 15 09:38:17 2006.
This document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CS302/2006S/Readings/scheme-1-6.html.

You may wish to validate this document's HTML ; Valid CSS! ; Check with Bobby

Samuel A. Rebelsky, rebelsky@grinnell.edu