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 associates variables with values in parallel.
• Let* associates variables with values sequentially.
• Letrec associates variables with values in the context of recursion.

## 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
```