Local bindings

Course links

Exercise 1

What are the values of the following let-expressions?

  1. (let ((tone '(f a))
          (call-me '(a l)))
      (append call-me tone '(l) tone))
    
  2. ;; Solutions to 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 ((total (+ 8 3 4 2 7)))
      (let ((mean (/ total 5)))
        (* mean mean)))
    

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

Exercise 2

Write a nested let-expression that binds a total of five names, a, b, c, d, and e, with a bound to 9387 and each subsequent name 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 names.

Exercise 3

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

Exercise 4

One of the traditional ways to compute the area of a triangle, given the lengths a, b, c of its sides, is to use Heron's formula:

A = √ (s · (s - a) · (s - b) · (s - c))

Here s is the semiperimeter of the triangle, (a + b + c) / 2.

Design and test a Scheme procedure that computes the area of a triangle, given the lengths of its sides, using Heron's formula.

Exercise 5

Here is a procedure that takes a non-empty list of lists as argument and returns the longest of those lists (or one of the longest, if there is a tie).

;;; longest-list-in-list: identify and return the
;;; longest list in a non-empty list of lists.

;;; Given:
;;;   LS, a list of lists.

;;; Result:
;;;   LONGEST, a list.

;;; Precondition:
;;;   LS is not empty.

;;; Postconditions:
;;;   (1) LONGEST is an element of LS.
;;;   (2) No element of LS is longer than LONGEST.

(define longest-list-in-list
  (lambda (ls)
    (if (null? (cdr ls))
        (car ls)
        (longer-list (car ls)
                     (longest-list-in-list (cdr ls))))))

This definition of the longest-list-in-list procedure includes a call to the longer procedure, which returns the longer of two given lists:

;;; longer-list: return the longer of two given lists

;;; Givens:
;;;   LEFT and RIGHT, both lists.

;;; Result:
;;;   LONGER, a list.

;;; Preconditions:
;;;   None.

;;; Postconditions:
;;;   (1) LONGER is either LEFT or RIGHT.
;;;   (2) Neither LEFT nor RIGHT is longer than LONGER.

(define longer-list
  (lambda (left right)
    (if (<= (length right) (length left))
        left
        right)))

Revise the definition of longest-list-in-list so that the name longer-list is bound to the procedure that it denotes only locally, in a let-expression.

Note that there are two possible ways to do this: The definiens of longest-list-in-list can be a lambda-expression with a let-expression as its body, or it can be a let-expression with a lambda-expression as its body. Does the order of nesting affect what happens when the procedure is invoked? If so, which arrangement is better? Why?

I am indebted to Professor Ben Gum for his contributions to the development of this lab.