CSC 153 Grinnell College Spring, 2005
 
Computer Science Fundamentals
Laboratory Exercise
 

Local Bindings

Goal:

This laboratory exercise explores three new, but related, mechanisms to associate values with variables:

Let

  1. What are the values of the following let-expressions?

    1. (let ((tone "fa") (call-me "al"))
        (string-append call-me tone "l" tone))
      
    2. ;; solving the quadratic equation x^2 - 5x + 4
      ;;
      (let ((discriminant (- (* -5 -5) (* 4 1 4))))
        (list (/ (+ (- -5) (sqrt discriminant)) (* 2 1))
              (/ (- (- -5) (sqrt discriminant)) (* 2 1))))
      
    3. (let ((sum (+ 8 3 4 2 7)))
        (let ((mean (/ sum 5)))
          (* mean mean)))
      

    You may use Chez Scheme to help you answer these questions, but be sure you can explain how it arrived at its answers.

  2. Consider the following count-all-symbols procedure which counts the number of symbols that appear in a list or any of its sublists. A sample run also is given:

    (define count-all-symbols
      (lambda (ls)
      ;Pre-condition:  ls is a list
      ;Post-condition:  returns the number of symbols on ls or any sublist of ls
        (cond ((null? ls) 0)
              ((symbol? (car ls)) (+ 1 (count-all-symbols (cdr ls))))
              ((list? (car ls))
               (+ (count-all-symbols (car ls)) (count-all-symbols (cdr ls))))
              (else (count-all-symbols (cdr ls))))))
    
    (count-all-symbols '(((a b) c) d (e (f)))) ===> 6
    

    Rewrite this count-all-symbols procedure, using a let-expression to consolidate repeated subexpressions in the same manner.

Let*

  1. Write a nested let-expression that binds a total of five variables, a, b, c, d, and e, with a bound to 9387 and each subsequent variable bound to a value twice as large as the one before it -- b should be twice as large as a, c twice as large as b, and so on. The body of the innermost let-expression should compute the sum of the values of the five variables.

  2. Write a let*-expression equivalent to the let-expression in the previous exercise.

  3. Rewrite the longest-on-list procedure from the first lab on recursion so that it incorporates the longer-string procedure by means of a local binding.

Letrec

  1. Write a letrec-expression in which (a) the identifier last-of-list is locally bound to a procedure that finds and returns the last element of a given list, and (b) the body of the expression computes the sum of the last elements of the lists (3 8 2), (7), and (8 5 9 8), invoking last-of-list three times.

The letrec-expression makes it possible to include binding specifications for mutually recursive procedures in the same binding list:

(letrec ((up-sum
          (lambda (ls)
            (if (null? ls)
                0
                (+ (down-sum (cdr ls)) (car ls)))))
         (down-sum
          (lambda (ls)
            (if (null? ls)
                0
                (- (up-sum (cdr ls)) (car ls))))))
  (up-sum '(1 23 6 12 7))
)
===> -21
  1. A non-empty list is an s-n-alternator if its elements are alternately symbols and numbers, beginning with a symbol. It is an n-s-alternator if its elements are alternately numbers and symbols, beginning with a number.

    Using the letrec definitions of up-sum and down-sum as an example, write a letrec-expression in which (a) the identifiers s-n-alternator? and n-s-alternator? are bound to mutually recursive predicates, each of which determines whether a given non-empty list has the indicated characteristic, and (b) the body invokes each of these predicates to determine whether the list (2 a 3 b 4 c 5) fits either description.

This document is available on the World Wide Web as

http://www.walker.cs.grinnell.edu/courses/153.sp05/labs/local-bindings.shtml

created February 26, 1997
last revised February 1, 2005
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.