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-five (45) 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?
-
Describe the benefits of preprocessing a syntactic abstraction to
functions that process language expressions, such as
is-declared?
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
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: Do you think Caitlin Clark and the University of Iowa women's basketball team will win the NCAA championship this weekend?
Problem 3
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 4
Answer each of these questions about lexical addresses.
-
Write the lexical address for each variable reference, 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 language details on the next page.
((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 (lambda (exp list-of-decls) (cond ((varref? exp) (lexical-address-for exp list-of-decls 0)) ((if? exp) (make-if (lexical-address-helper (if->test exp) list-of-decls) (lexical-address-helper (if->then exp) list-of-decls) (lexical-address-helper (if->else exp) list-of-decls))) ((app? exp) (make-app (lexical-address-helper (app->proc exp) list-of-decls) (map (lambda (e) (lexical-address-helper e list-of-decls)) (app->args exp)))) ((lambda? exp) (make-lambda (lambda->params exp) (lexical-address-helper (lambda->body exp) (cons (lambda->params exp) list-of-decls)))) (else (error 'lexical-address "unknown exp ~a" exp) ))))