Quiz 3: Syntactic Abstraction
Instructions
- The quiz consists of five questions.
- Read through all the questions before you begin. It is worth your time to plan ahead.
- The quiz is worth 60 points. Each question is worth twelve points.
-
Write your answers in the space provided on the exam.
You may write on the back of a page if you need more space. - Partial credit will be given where possible, so show your work.
- The quiz lasts forty (40) minutes. It is due at 1:45 PM.
Problem 1
Give brief answers to each of these questions about syntactic abstraction. One sentence each should be sufficient for the first and second bullets — two sentences each max.
- What does it mean to say that a language feature is a syntactic abstraction?
-
How does preprocessing a syntactic abstraction benefit the
implementers of functions that process language expressions,
such as
occurs-bound?andfree-vars? -
Write a Racket expression that is equivalent to the following
but which uses only core features of the language.
(cond ((eq? key 'name) "Intro") ((eq? key 'number) "1510") (else ""))
Problem 2
Write a recursive function (and->if and-exp),
where and-exp is described by this grammar:
<and-exp> ::= (and . <arglist>)
<arglist> ::= '()
| (<symbol> . <arglist>)
and->if returns an equivalent if
expression. For example:
> (and->if '(and)) ; and is true with no arguments #t > (and->if '(and x y)) '(if x (if y #t #f) #f) > (and->if '(and a b c d e)) '(if a (if b (if c (if d (if e #t #f) #f) #f) #f) #f)
Hint: Make and->if an interface
procedure that strips the symbol 'and from the
front of its argument and calls a helper function
on the list of symbols.
Problem 3
Answer these questions about local variables as a syntactic abstraction.
The designers of your favorite programming language have decided to eliminate local variables from the next version of language. "No problem", you think. "Local variables are a syntactic abstraction."
- Explain briefly (1-2 sentences) how we can compute the same results without a local variable using a semantically equivalent form that binds a value to the variable's name.
-
Demonstrate your solution using this snippet of Python code,
or with the equivalent code in Racket:
miles = speed * time/60 return miles/numdays
- For a quick two points: Michael B. Jordan or Timothée Chalamet? "Neither" is also a valid answer.
Problem 4
Answer each of these questions about lexical addresses.
-
Write the lexical address for each variable reference
in these expressions, in the form
(v : d p).(lambda (n) (lambda (f g) (+ (f n) (g n)))) (lambda (x y) (lambda (y z) ( (lambda (x z) ((y z) (x y))) y x))) -
Give equivalent Racket expressions for these expressions
in lexical address form, or explain why there is no such
expression.
(lambda (a b) (lambda (c d e) ((: 1 1) (: 0 2) (: 0 1)))) (lambda 3 (lambda 2 ((: 0 0) (: 1 2) ((: 0 1) (: 1 0)) (: 0 2))))
Problem 5
On Homework 7, we added a let expression to our
little language.
Add a case to the definition of
lexical-address-helper
so that it can handle let expressions.
See the next page for a reminder of the language details.
((let? exp) ; a new case for let expressions
; FILL-IN-THE-BLANK
)
The Little Language for Problem 5
Problem 5 uses the little language we worked with on our
lexical addressing exercise in Sessions 19-20,
extended with a let expression.
<exp> ::= <varref>
| (lambda (<var>*) <exp>)
| (<exp> . <exp>*)
| (if <exp> <exp> <exp>)
| (let (<var> <exp>) <exp>) <--- new from Homework 7
Like a Racket let expression,
this let expression creates a new block declaring
an identifier. The region of the local variable is the body
of the let expression. References to a local
variable within the body of the let are at a
depth of 0. For example:
> (lexical-address '(let (x n)
(f (g x))))
'(let (x (n : 0 0))
((f : 1 1) ((g : 1 2) (x : 0 0))))
> (lexical-address '(let (width n)
(let (height m)
(f height (* width width)))))
'(let (width (n : 0 0))
(let (height (m : 1 1))
((f : 2 2) (height : 0 0) ((* : 2 3) (width : 1 0) (width : 1 0)))))
Use the syntax procedures for let expressions
to write your code:
let? make-let let->var let->val let->body
The Existing Code for lexical-address-helper
(define (lexical-address-helper exp decls)
(cond ((varref? exp)
(make-lex-addr exp decls 0))
((if? exp)
(make-if (lexical-address-helper (if->test exp) decls)
(lexical-address-helper (if->then exp) decls)
(lexical-address-helper (if->else exp) decls)))
((app? exp)
(make-app (lexical-address-helper (app->proc exp) decls)
(map (lambda (e)
(lexical-address-helper e decls))
(app->args exp))))
((lambda? exp)
(make-lambda (lambda->params exp)
(lexical-address-helper
(lambda->body exp)
(cons (lambda->params exp) decls))))
(else (error 'lexical-address "unknown exp ~a" exp) )))