13 Midterm
13 Midterm
Instructions: You have 150 minutes to complete this closed-book, closed-note, closed-computer exam. Please
write all answers in the provided space. You’re free to write your answers in Korean.
1) (5pts) Rewrite the following FWAE code in FAE, that is, rewrite it without using with:
1
3) (5pts) Which of the following produce different results in an eager language and a lazy language? Both
produce the same result if they both produce the same number or they both produce a procedure (even
if the procedure doesn’t behave exactly the same when applied). Show the results of each expression
in an eager language and a lazy language.
eager: lazy:
eager: lazy:
eager: lazy:
eager: lazy:
eager: lazy:
2
5) (5pts) Explain why the following code is an infinite loop and describe how to break the infinite loop:
1 (let ([fac
2 (let ([facX
3 (lambda (facX)
4 (let ([fac (facX facX)])
5 (lambda (n)
6 (if (zero? n)
7 1
8 (* n (fac (- n 1)))))))])
9 (facX facX))])
10 (fac 10))
6) (5pts) The following code is an implementation of the interpreter for FAE. Describe whether the code
implements static scope or dynamic scope, and why. Then, explain how to change the code to imple-
ment the other scoping semantics:
3
7) (5pts) In our implementation of the interpreter for LFAE, we call the strict function to enforce
evaluation. Where did we call the strict function in our implementation? If we instead call the
strict function when we look up identifiers, what difference would it make?
Write an example showing the need for the nested strict call.
4
9) (5pts) The following strict code results in redundant evaluations:
(define-type LFAE-Value
[numV (n number?)]
[closureV (param symbol?) (body LFAE?) (ds DefrdSub?)]
[exprV (expr LFAE?) (ds DefrdSub?)
(value (box/c (or/c false LFAE-Value?)))])
Rewrite the above strict code using cached strict results.
5
10) (10pts) The following code is an excerpt from the implementation of the interpreter for BFAE:
In BMFAE, we introduce variables so that DefrdSub maps names (symbols) to addresses (integers) and
Store maps addresses (integers) to values (BMFAE-Value). Rewrite the above app case for BMFAE.
6
11) (10pts) Change the implementation of setbox in interp for BFAE so that the old value of the box is
dropped (i.e., replaced with the new value) instead of merely hidden by the outside-in search order of
store-lookup. Define your helper function with its purpose and contract.
12) (10pts) Extend the implementation of interp for BFAE with with. Explain why or why not you use
interp-two.
7
13) (10pts) Given the following expression:
{{fun {b1}
{{fun {b2}
{seqn {setbox b1 8}
{openbox b2}}}
b1}}
{newbox 7}}
write out the arguments to and results of interp each time it is called during the evaluation of a
program. Write them out in the order in which the calls to interp occur during evaluation.
Write down the environments and stores using the {} notation, not using the more verbose data
constructors. Also, use an arrow notation for both the store and the environment.
An example, if the first call to interp were:
exp: {+ x y}
env: {x -> (numV 3), y -> (numV 4)}
sto: {}
ans: (numV 7) {}
exp: x
env: {x -> (numV 3), y -> (numV 4)}
sto: {}
ans: (numV 3) {}
exp: y
env: {x -> (numV 3), y -> (numV 4)}
sto: {}
ans: (numV 4) {}
Note that the environment and store read in order from left to right.
8
9
10
14) (10pts) Consider the following language <MYE>:
(define-type MYE-Value
[numV (n number?)]
[boxV (address integer?)])
and an environment maps names to addresses and a store maps addresses to values:
(define-type DefrdSub
[mtSub]
[aSub (name symbol?) (address integer?) (rest DefrdSub?)])
(define-type Store
[mtSto]
[aSto (address integer?) (value MYE-Value?) (rest Store?)])
– The value of an identifier <id> is the value in the store at the address denoted by the identifier
in the environment.
– The value of {* <id>} is the value in the store at the address denoted by the value of the identifier.
– The value of {& <id>} is the address denoted by the identifier in the environment.
– The evaluation of {set <id> <MYE>} maps the address denoted by the identifier to the value of
<MYE>, which is the value of the whole expression.
– The evaluation of {set* <id> <MYE>} maps the address denoted by the value of the identifier to
the value of <MYE>, which is the value of the whole expression.
Using the following functions to lookup environments and stores:
11
fill in the blanks below:
12
#lang plai
(define-type BFAE
[num (n number?)]
[add (lhs BFAE?) (rhs BFAE?)]
[sub (lhs BFAE?) (rhs BFAE?)]
[id (name symbol?)]
[fun (param symbol?) (body BFAE?)]
[app (fun-expr BFAE?) (arg-expr BFAE?)]
[newbox (val-expr BFAE?)]
[setbox (box-expr BFAE?) (val-expr BFAE?)]
[openbox (box-expr BFAE?)]
[seqn (first BFAE?) (second BFAE?)])
(define-type BFAE-Value
[numV (n number?)]
[closureV (param symbol?) (body BFAE?) (ds DefrdSub?)]
[boxV (address integer?)])
(define-type DefrdSub
[mtSub]
[aSub (name symbol?) (value BFAE-Value?) (rest DefrdSub?)])
(define-type Store
[mtSto]
[aSto (address integer?) (value BFAE-Value?) (rest Store?)])
(define-type Value*Store
[v*s (value BFAE-Value?) (store Store?)])
;; -------------------------------------------------------------
;; -------------------------------------------------------------
;; num-op : (number number -> number) -> (BFAE-Value BFAE-Value -> BFAE-Value)
(define (num-op op x y) (numV (op (numV-n x) (numV-n y))))
(define (num+ x y) (num-op + x y))
(define (num- x y) (num-op - x y))
13
;; store-lookup : number Store -> BFAE-Value
(define (store-lookup addr st)
(type-case Store st
[mtSto () (error ’store-lookup "unallocated")]
[aSto (sto-addr val rest-st)
(if (= addr sto-addr)
val
(store-lookup addr rest-st))]))
;; -------------------------------------------------------------
;; interp-two : BFAE BFAE DefrdSub Store (Value Value Store -> Value*Store)
;; -> Value*Store
(define (interp-two expr1 expr2 ds st handle)
(type-case Value*Store (interp expr1 ds st)
[v*s (val1 st2)
(type-case Value*Store (interp expr2 ds st2)
[v*s (val2 st3)
(handle val1 val2 st3)])]))
14