Sample Final 2Date: Wednesday, April 23rd |
AdministrativeThis exam was given last year |
| |||||||||||||||||||||||||
Remember: the correct answers are short. Also, questions that ask for a verbal answer rather than code should still be answered correctly and based on facts.
Question 1: Scheme Programming | 20 pts |
(letrec ([notify (lambda ()
(printf "working on ~s...\n" (list 'foo 3))
(sleep 1)
(notify))])
(car (pcons (foo 3) (notify)))) |
> (define (fib n) ...)
> (define fib* (slow-wrapper fib 'fib))
> (fib* 35)
working on (fib 35)...
...
working on (fib 35)...
9227465 |
Question 2: Language Extension: Extending Scheme | 20 pts |
;; pmap : (A -> B) (Listof A) -> (Listof B)
;; Similar to `map', except that all function applications happen at the
;; same time.
(define (pmap f l)
(if (null? l)
null
(pcons (f (car l)) (pmap f (cdr l))))) |
(pcall fun x ...) |
Question 3: Language Extension: Extending (Compiled) Toy | 15 pts |
Question 4: Language Features | 25 pts |
(define (pcons x y)
(pcall cons x y)) |
Question 5: Programming in Lazy Scheme | 20 pts |
;; append : (Listof A) (Listof A) -> (Listof A)
(define (append l1 l2)
(if (zero? (length l1))
l2
(cons (car l1) (append (cdr l1) l2)))) |
Question 6: Type System | 20 pts |
Γ |- n : Number
Γ |- x : Γ(x)
Γ |- a : Number Γ |- b : Number
|
{with {x : τ v} E} ==> {call {fun {x : τ} E} v} |
{bind* {{x1 : τ1 v1} {x : τ v} ...} E} ==> {with {x1 : τ1 v1} {bind* {{x : τ v} ...} E}}
{bind* {} E} ==> E |
The following are parts of the extended TOY compiler implementation from HW#7:
<TOY> ::= <num>
| <id>
| { bind {{ <id> <TOY> } ... } <TOY> <TOY> ... }
| { bindrec {{ <id> <TOY> } ... } <TOY> <TOY> ... }
| { fun { <id> ... } <TOY> <TOY> ... }
| { rfun { <id> ... } <TOY> <TOY> ... }
| { if <TOY> <TOY> <TOY> }
| { set! <id> <TOY> }
| { <TOY> <TOY> ... }...;; compile : TOY -> (env -> VAL)
;; compiles TOY expressions to Scheme procedures
(define (compile expr)
(unless (unbox compiler-enabled?)
(error 'compile "compiler disabled"))
(cases expr
[(Num n)
(let ([v (ScmV n)]) ; make the ScmV value in advance
(lambda (env) v))]
[(Id v)
(lambda (env) (unbox (lookup v env)))]
[(Bind names exprs bound-body)
(let ([compiled-exprs (map compile exprs)]
[compiled-body (compile-body bound-body)])
(lambda (env)
(compiled-body
(extend names
(map (lambda (c) (c env)) compiled-exprs)
env))))]
[(BindRec names exprs bound-body)
(let ([compiled-exprs (map compile exprs)]
[compiled-body (compile-body bound-body)])
(lambda (env)
(compiled-body (extend-rec names compiled-exprs env))))]
[(Fun names bound-body)
(let ([compiled-body (compile-body bound-body)])
(lambda (env) (FunV names compiled-body env)))]
[(RFun names bound-body)
(let ([compiled-body (compile-body bound-body)])
(lambda (env) (RFunV names compiled-body env)))]
[(Call fun-expr arg-exprs)
(let ([compiled-fun (compile fun-expr)]
[compiled-args (map compile arg-exprs)]
[id-args (and (andmap Id? arg-exprs)
(map Id-name arg-exprs))])
(lambda (env)
(let ([fval (compiled-fun env)]
;; delay the evaluation of arguments (use if needed)
[arg-vals (lambda ()
(map (lambda (c) (c env)) compiled-args))])
(cases fval
[(PrimV proc) (proc (arg-vals))]
[(FunV names compiled-body fun-env)
(compiled-body (extend names (arg-vals) fun-env))]
[(RFunV names compiled-body fun-env)
(if id-args
(let ([boxes (map (lambda (id) (lookup id env))
id-args)])
(compiled-body (extend-boxes names boxes fun-env)))
(error 'call "rfun expects only variable names"))]
[else (error 'call "got a non-function: ~s" fval)]))))]
[(If cond-expr then-expr else-expr)
(let ([compiled-cond (compile cond-expr)]
[compiled-then (compile then-expr)]
[compiled-else (compile else-expr)])
(lambda (env)
((if (cases (compiled-cond env)
[(ScmV v) v] ; Scheme value => use as boolean
[else #t]) ; other values are always true
compiled-then
compiled-else)
env)))]
[(Set id expr)
(let ([compiled-expr (compile expr)])
(lambda (env)
(set-box! (lookup id env) (compiled-expr env))
bogus))]))