Sample Midterm Exam for Programming Languages | COMP 311, Exams of Programming Languages

Material Type: Exam; Class: PROGRAMMING LANGUAGES; Subject: Computer Science; University: Rice University; Term: Fall 2007;

Typology: Exams

Pre 2010

Uploaded on 08/18/2009

koofers-user-qiw
koofers-user-qiw 🇺🇸

9 documents

1 / 12

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Comp 311: Sample Midterm Examination
October 29, 2007
Name:
Id #:
Instructions
1. The examination is closed book. If you forget the name for a Scheme
operation, make up a name for it and write a brief explanation in the
margin.
2. Fill in the information above and the pledge below.
3. There are 6 problems on the exam, totaling 100 points on the exam.
4. You have three hours to complete the exam.
Pledge:
1
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Sample Midterm Exam for Programming Languages | COMP 311 and more Exams Programming Languages in PDF only on Docsity!

Comp 311: Sample Midterm Examination

October 29, 2007

Name:

Id #:

Instructions

  1. The examination is closed book. If you forget the name for a Scheme operation, make up a name for it and write a brief explanation in the margin.
  2. Fill in the information above and the pledge below.
  3. There are 6 problems on the exam, totaling 100 points on the exam.
  4. You have three hours to complete the exam.

Pledge:

Problem 1. (10 points) Al Gaulle, a programmer for Kludge, Inc., is de- signing a simple extension language for a business software package. He is proposing the grammar for imperative Jam (Project 4) except for the following revision to the syntax for if-expressions:

<if-exp> ::= if then else | if then

Do you see any problems with this specification (besides the questionable use of Jam as the foundation for his language), particularly his revision to Jam syntax? State your criticism precisely.

His extension is a flawed design because the syntax is ambiguous. There are two distinct parse trees for the following expression:

if flag1 then if flag2 then foo() else bar()

The else clause can be associated with either of the two if expressions.

if flag1 then (if flag2 then foo() else bar())

or

if flag1 then (if flag2 then foo()) else bar()

Problem 3. (20 points) Recall that Scheme let construct (which is not recursive) expands into lambda expressions as follows:

(let [(x1 E1) (x2 E2) ... (xn En)] E)}

abbreviates

((lambda (x1 x2 ... xn) E) E1 E2 ... En) Similarly, the let* construct expands into let expressions as follows:

(let* [(x1 E1) (x2 E2) ... (xn En)] E)

abbreviates

(let [(x1 E1)] (let [(x2 E2)] ... (let [(xn En)] E)...))

The other binding form in the Scheme let family is letrec; it has the same scoping rules as the Jam recursive let. For each of the two expressions on the next page, circle each binding occurrence of a variable and draw arrows from each bound occurrence back to the corresponding binding occurence. For example, given the expression

(lambda (x) (+ x 1))

the correct answer is:

(lambda (x) (+ x 1))

  1. (let* [(fib (lambda (n) (letrec [(fibhelp (lambda (m fn-1 fn-2) (let [(fn (+ fn-1 fn-2))] (if (zero? m) fn (fibhelp (sub1 m) fn fn-1)))))] (if (< n 2) 1 (fibhelp (sub1 n) 1 1))))) (fib100 (fib 100))] (* fib100 fib100))
  2. (let* [(pair (lambda (x y) (let [(x x) (y y)] (lambda (msg) (cond [(eq? msg ’first) x] [(eq? msg ’second) y] [else (error ’pair "illegal method name ~a" msg)]))))) (pair (pair 1 2))] (pair ’first))

(define-struct let-exp (id rhs body))

(define Eval (lambda (exp env) (cond ; bool, prim, unop, and if eliminated for pedagogic simplicity [(num-exp? exp) (num-exp-arg exp)] [(id-exp? exp) (binding-val (id-lookup (id-exp-arg exp) env))] [(biop-exp? exp) (local [(define rator (biop-exp-rator exp)) (define rand1 (Eval (biop-exp-rand1 exp) env)) (define rand2 (Eval (biop-exp-rand2 exp) env))] (cond [(eq? rator ’+) (+ rand1 rand2)] [(eq? rator ’-) (- rand1 rand2)] [else (error ’Eval "unrecognized binary operator ~a" rator)]))] [(map-exp? exp) (make-closure (map-exp-var exp) (map-exp-body exp) env)] [(app-exp? exp) (Apply (Eval (app-exp-rator exp) env) (Eval (app-exp-rand exp) env))]

[(let-exp? exp) (local [(define var (let-exp-id exp)) (define rhs (let-exp-rhs exp)) (define body (let-exp-body exp)) (define let-env (cons (make-binding var (void)) env))] (begin (set-binding-val! let-env (Eval rhs let-env)) (Eval body new-env)))]

[else (error ’Eval "illegal expression: ~a" exp)])))

(define extend (lambda (env var val) (cons (make-binding var val) env)))

(define id-lookup ; returns binding pair not binding-val (lambda (id env) (cond [(eq? id (binding-var (car env))) (car env)] [else (id-lookup id (cdr env))])))

(define Apply (lambda (head arg-val) ; head must be a closure (local

[(define parm (closure-parm head)) (define body (closure-body head)) (define env (closure-env head))] (Eval body (extend env parm arg-val)))))

The additional code required to support recursive let is enclosed above between pairs of horizontal lines.

(ii) Assume that Jam passes parameters by value rather than by name. Show the major steps in the evaluation of the preceding expression. Please use abbreviations to shorten your trace.

Problem 6. (20 points) Al Gaulle has designed the ultimate Algol dialect supporting passing parameters by value, by name, by reference, by result, and by value-result. For value-result parameter passing, assume that the argument evaluated once on entry to the procedure and that the resulting location is used on exit. Consider the following Algol-like program (written in Java-like notation):

int i,j,a[5]; // a is an 5 element array with indices 0- void swap(int x, int y) { int temp = x; x = y; y = temp; } for (j = 0; j < 5; j++) a[j] := j;

i := 1; swap(i,a[i+1]); write(i,a[2]);

What numbers does the program print if both parameters in swap are passed by:

  1. value? Just prior to the swap statement, a = {0,1,2,3,4} and i = 1. The call on swap has no effect on the actual parameters since they are passed by value. Hence, the program outputs:

1 2

  1. reference? Just prior to the swap statement, a = {0,1,2,3,4} and i = 1. The call on swap swaps the contents of i and a[2], yielding a = {0,1,1,3,4} and i = 2. Hence, the program outputs:

2 1

  1. name? Just prior to the swap statement, a = {0,1,2,3,4} and i = 1. Let us trace the call on swap in detail. Within the body of swap, x is