Quiz 2
Instructions
- The quiz consists of five questions.
- Read all the questions thoroughly before you begin. It is worth your time to plan ahead!
- The quiz is worth 60 points. Each question is worth twelve points.
- Partial credit will be given where possible, so show your work.
- The quiz lasts thirty (40) minutes. It is due at 1:45 PM.
Because the primary goal of this portion of the course is to
demonstrate the ability to write recursive programs, you
may not use any built-in function that does
the recursion for you, such as map
,
filter
, or reverse
.
Problem 1
Write a structurally recursive function
(list-of? type? lst)
that takes two arguments: a boolean predicate type?
and a list lst
.
list-of?
returns a true if every item in
lst
is of the type?
, and false otherwise.
For example:
> (list-of? number? '(1 2 3 4 5)) #t > (list-of? number? '(1 2 3 "Eugene" 4 5)) ; "Eugene" is not a number #f > (list-of? boolean? '(#t #f #t)) #t > (list-of? list? '((1 2 3) () (a . b))) ; (a . b) is not a list #f
Problem 2
Write a mutually recursive function (nlist++ nlst)
that takes an n-list as an argument:
<n-list> ::= () | (<number-expression> . <n-list>) <number-expression> ::= <number> | <n-list>
nlist++
returns an n-list of the same shape as its
argument, but with every number incremented by 1. For example:
> (nlist++ '(1 (4 (9 (16 25)) 36 49) 64)) '(2 (5 (10 (17 26)) 37 50) 65) > (nlist++ '(0 1 2 3)) '(1 2 3 4)
nlist++
must be mutually recursive with the
function numexp++
, which increments the numbers in a
number-expression.
Problem 3
Write a structurally recursive function
(list-index s los)
that takes two arguments,
a symbol s
and a list of symbols los
:
<list-of-symbols> ::= () | (<symbol> . <list-of-symbols>)
list-index
returns the 0-based position of the first
s
in the list. If s
does not occur in
the list, it returns -1. For example:
> (list-index 'd '(a b c d e f d)) 3 > (list-index 'g '(a b c d e f d)) -1
You'll need an interface procedure here, so that each recursive call can know the position of the current item.
Problem 4
Write brief answers for each of the following items. One phrase, sentence, or Racket expression is sufficient for each.
- What does it mean to say that a function is structurally recursive?
- We saw how we could use program derivation to merge a helper function back into the function that calls it. Why wouldn't we want to use program derivation to merge syntax procedures back into a function that uses them?
- In what way can a compiler generate more efficient code for a tail recursive function?
-
The expression
(occurs-free? x exp)
is not always equal to the expression(not (occurs-bound? x exp))
for a givenx
andexp
. Give an expression in the little language that illustrates why.
(You can see the BNF definition of the little language on the next page.)
Extra Credit. There are two ways in which this is true. Give distinct examples that illustrate both ways.
Problem 5
Write a structurally recursive function
(is-declared? v exp)
that takes two arguments:
v
, a symbol, and exp
, an expression in
our little language:
<exp> ::= <varref> | (lambda (<var>) <exp>) | (<exp> <exp>)
is-declared?
returns true if v
is
declared anywhere in exp
, and false otherwise.
Recall that:
-
Only a
lambda
expression can declare a variable. -
A
lambda
expression can occur anywhere that expects an expression.
For example:
> (is-declared? 'y 'y) #f > (is-declared? 'x '(lambda (x) x)) #t > (is-declared? 'x '(lambda (y) x)) #f > (is-declared? 'x '( (lambda (y) y) ; x is not declared here (lambda (x) x) )) ; but x is declared here #t
You must use these syntax procedures for the little language, as provided in class.
exp? varref? lambda? app? lambda->param app->proc lambda->body app->arg