Solutions to Midterm #2

This midterm was taken in class on March 13, 1998. Two versions of this exam were distributed. The original questions appear in black text, correct solutions appear in green, and other comments, in blue.

1. (25 points.) Define and provide a descriptive example of each of the following concepts

 (a) Static property: A property is said to be static if it can be inferred completely from the program's text. Examples are the scope of variables in lexically scoped languages such as Pasal, C, C++, Java, Scheme; the type of variables and functions in typed languages such as Pascal, C, C++, and Java. (See page 55 of EOPL.)
(b) Opaque data type: A data type is said to be opaque if its implementation is hidden and inaccessible to the user. The primitive (i.e., built in) data types of Scheme (empty list, string, char, number, symbol, boolean) are opaque. In contrast, the data types of C are transparant because every memory address can in principle be accessed and modified. (See pages 90 of EOPL.)
(c) Beta-conversion: A reduction rule in the lambda calculus that describes how the formal parameters in a lambda expression are assigned values, and how the body of the expression is evaluated in turn. Symbolically, if E and M are expressions in the lambda calculus, and x is a variable, then

((lambda (x) E) M) = E[M/x].

(See page 105 of EOPL.)

 

 (a) Lexically scoped language: A programming language is said to be lexically scoped if the scope of each declared variable is a static property, that is, the scope is completely inferrable from the text of the program. Pasal, C, C++, Java, Scheme are all lexically scoped languages (See page 59 of EOPL.)
(b) Primitive data type: A data type is said to be primitive if it is built in. The primitive data types of Scheme (empty list, string, char, number, symbol, boolean) are opaque. (See pages 90 of EOPL.)
(c) Alpha-conversion: A variable substitution rule in the lambda calculus that allows one to rename one or more formal parameters of a lambda expression. Symbolically, if E and M are expressions in the lambda caluculs, x is a variable, and y is any variable that does not occur free in E, then

(lambda(x)E) = (lambda(y)E[y/x])

(See page 64 of EOPL.)



2. (15 points.) Find an equivalent Scheme expression to the following that uses a lambda expression in place of let.

(let ((r (cdr mumbo))
      (s (cdr dumbo)))
   (append (s mumbo) (r jumbo)))

((lambda (r s)
   (append (s mumbo) (r jumbo)))
 (cdr mumbo)
 (cdr dumbo))



 
(let ((x (car mumbo))
      (y (car jumbo)))
   (if (eq? x y)
     (x mumbo)
     (y jumbo)))

((lambda (x y)
   (if (eq? x y)
     (x mumbo)
     (y jumbo)))
 (car mumbo)
 (car jumbo)

3. (15 points.) Rewrite the following expression and replace each variable reference that occurs bound by its lexical address in the form (var:depth position).

(lambda (x y z)
  (if (zero? x)
    ((lambda (y z) (y (z x)))
     (lambda (y) (z y))
     y)
    (cons z '(y x))))

((lambda (x y z)
   (if (zero? (x:0 0))
     ((lambda (y z)
        ((y:0 0) ((z:0 1) (x:1 0)))
      (lambda (y) ((z:1 2) (y:0 0))
      (y:0 1))
     (cons (z:0 2) '(y x))))
 
(lambda (a b c)
  (if (null? a)
    ((lambda (c d) (c (a d)))
     (lambda (a) (b a))
     c)
    (cons c '(a b))))

(lambda (a b c)
  (if (null? (a:0 0))
    ((lambda (c d) 
      ((c:0 0) ((a:1 0) (d:0 1))))
     (lambda (a) ((b:1 1) (a:0 0)))
     (c:0 2))
    (cons (c:0 2) '(a b))))

4. (15 points.) Consider the following grammar and abstract syntax for the lambda 
calculus discussed in out textbook:
<exp> ::= <number>                    lit (datum)
       |  <varref>                    varref (var)
       |  (lambda (<var>) <exp>))     lambda (formal body)
       |  (<exp> <exp>)               app (rator rand)

Draw an abstract syntax tree for the expression [indicated below]. Be sure to label each internal node with the appropriate production name, and each edge with the correct nonterminal occurrence.

 

   

 

5. (15points.) Write an implementation of the Scheme procedure reverse, which accepts a single list as an argument, and returns the list in reverse order as shown:

> (reverse '(x y z))
(z y x)

Solution: The preferred approach uses letrec:

(define reverse
  (lambda (lst)
    (letrec ((reverse-aux 
               (lambda (lst out)
                 (if (null? lst)
                   out
                   (reverse-aux (cdr lst) 
                                (cons (car lst) out))))))
       (reverse-aux lst '()))))

6. (15points.) A palidromic list of symbols reads the same forwards as it does backwards, e.g., (a b c b a ) and (a b b a). Write a Scheme predicate (palindrome? los) that can be used to determine if los is a palindromic list of symbols.

> (plaindrome? '(a b b a))
#t
> (palindrome? '(a b c))
#f
> (palindrome? '(a () a)) ; not a list of symbols!
#f

Solution:

(define palindrome?
  (lambda (los)
    (letrec ((los-eq? 
               (lambda (los1 los2)
                 (cond
                   ((null? los1) (null? los2))
                   ((null? los2) #f)
                   (else (let ((s1 (car los1))
                               (s2 (car los2)))
                           (cond ((not (symbol? s1)) #f)
                                 ((not (symbol? s2)) #f)
                                 ((not (eq? (car los1) (car los2))) #f)
                                 (else (los-eq? (cdr los1) (cdr los2))))))))))
      (los-eq? los (reverse los)))))


CS 103 Home Page
Robert Snapp's Home Page
(Last modified on March 14, 1998.)