Fundamentals of CS I (CS151 2001S)

Some More Notes on Local Bindings

A few of you have asked me to provide some more information on let and let*, including more examples. I hope that this document will help alleviate some of the confusion.

The let and let* procedures allow you to name values. There are three basic reasons to name values:

Here are some examples of each.

Clarity

Suppose we've decided to represent some compound value as a list. For example, we might want to represent someone's name as a five-value list (title, first-name, middle-name, last-name, suffix). Now, suppose we want to print the last name of all the people whose title is "Professor".

(define search-for-profs
  (lambda (people)
    (if (not (null? people))
        (begin
          (if (string=? (car (car people)) "Professor")
              (begin
                (display (list-ref (car people) 3))
                (newline)))
          (search-for-profs (cdr people))))))

Here's a sample call:

(search-for-profs
  (list (list "Professor" "Samuel" "Alexander" "Rebelsky" "")
        (list "Doctor" "Michelle" "Steele" "Rebelsky" "")
        (list "Professor" "Freda" "Gould" "Rebelsky" "")
        (list "Mister" "William" "" "Rebelsky" "")
        (list "Mister" "William" "Lloyd" "Rebelsky" "")
        (list "Mister" "Jonathan" "Bennett" "Rebelsky" "")))

One problem with this procedure is that may not be clear to the reader why we're taking the car of the car of people or element 3. Here is some clearer code.

(define search-for-profs
  (lambda (people)
    (if (not (null? people))
        (begin
          (let* ((one-person (car people))
                 (remaining-people (cdr people))
                 (title (car one-person))
                 (lastname (list-ref one-person 3)))
            (if (string=? title "Professor")
              (begin
                (display lastname))
                (newline)))
          (search-for-profs remaining-people)))))

Efficiency

Repeatability

Consider the problem of reading a value and printing out the type of value read. Here's one (incorrect) solution.

(display "Enter a value and I'll tell you its type: ")
(cond
  ((symbol? (read)) 
   (begin
     (display (read))
     (display " is a symbol")
     (newline)))
  ((string? (read)) 
   (begin
     (display (read))
     (display " is a string")
     (newline)))
  (else
   (begin
     (display "I can't figure out the type of ")
     (display (read))
     (newline))))

What's wrong with this? Well, every time that the code calls (read), the code attempts to read a new value. Hence, even if it reads a symbol for the first value, it still needs to read something else before printing the result. (Try it and see).

So, what should we do? We should read the value once and name it.

(display "Enter a value and I'll tell you its type: ")
(let ((val (read)))
  (cond
    ((symbol? val) 
     (begin
       (display val)
       (display " is a symbol")
       (newline)))
    ((string? val) 
     (begin
       (display val)
       (display " is a string")
       (newline)))
    (else
     (begin
       (display "I can't figure out the type of ")
       (display val)
       (newline)))))

 

History

Monday, 12 March 2001

Monday, 9 April 2001

 

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

This page was generated by Siteweaver on Thu May 3 23:10:30 2001.
This page may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CS151/2001S/more-let.html.
You may validate this page's HTML.
The source was last modified Mon Apr 9 13:54:12 2001.