Programming Languages and Paradigms

Spring Semester 2018

- The exam consists of five questions. Be sure that you have all five and that they are all legible.
- Read all questions and their instructions thoroughly before you begin. It is always worth your time to plan ahead!
- You have also been given two blank pages. Write your answers on the blank pages.
- The exam is worth 60 points. Each question is worth twelve points.
- Points will be awarded based on your explicit answers. Partial credit will be given where possible, so show all of your work.
- Because the primary goal of this portion of the course is to
demonstrate the ability to write recursive programs, you
any built-in function that does the recursion for you, such as*may not use*`map`,`filter`, or`reverse`. - The quiz lasts forty (40) minutes. It is due at 1:45 PM.

- Write a structurally recursive function
that merges two sorted lists.`(merge less-than? lst1 lst2)``lst1`and`lst2`are lists of values in the order specified by the`less-than?`predicate.returns a single sorted list containing all the values in`merge``lst1`and`lst2`. For example:> (merge < '(1 4) '(1 2 8)) '(1 1 2 4 8) > (merge > '(4 1) '(8 2 1)) '(8 4 2 1 1) ; string-ci<? is a case-insensitive < function for strings > (merge string-ci<? '("a" "an" "Bill" "Eugene") '("ask" "blog" "edgy")) '("a" "an" "ask" "Bill" "blog" "edgy" "Eugene")

- Write a mutually-recursive function
that takes an n-list as an argument:`(nlist-add1 nlst)`<n-list> ::= () | (<number-expression> . <n-list>) <number-expression> ::= <number> | <n-list>

returns an n-list of the same shape as its argument, but with every number incremented by 1. For example:`nlist-add1`> (nlist-add1 '(1 (4 (9 (16 25)) 36 49) 64)) '(2 (5 (10 (17 26)) 37 50) 65)

must be mutually recursive with the function`nlist-add1`, which increments the numbers in a`numexp-add1`*number expression*. - Answer
**very briefly**the following questions. One phrase, sentence, or Racket expression is sufficient for each.

Two of the questions refer to the`sequence`function, which we have used occasionally this semester to generate a list of numbers between two values:(define sequence (lambda (m n) (if (> m n) '() (cons m (sequence (+ m 1) n)))))

- 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? - The
`sequence`function is not**tail recursive**. What does that statement mean, in terms of*the way the function is written*? - The
`sequence`function is not**tail recursive**. What does that statement mean, in terms of*the way the function executes at run time*? - The expression
(occurs-free?

is*x**exp*)**not**always equal to the expression(not (occurs-bound?

for a given*x**exp*))`x`and`exp`. Give an example that illustrates why.

*Extra Credit*. There are two ways in which this is true. Give distinct examples that illustrate both ways.

- We saw how we could use
- Write a structurally recursive function
that two arguments, a two-argument function`(counted-map f lon)``(f item position)`and a list of numbers`lon`:<list-of-numbers> ::= () | (<number> . <list-of-numbers>)

passes each number in the list to`counted-map``f`along with its 0-based position in the list. So, for

`'(3 2)`, it would evaluate`(f 3 0)`and`(f 2 1)`.returns a list of the results. For example:`counted-map`; each item is multiplied by its position > (counted-map * '(3 2 -4)) ; 3*0, 2*1, (-4)*2 '(0 2 -8) ; each item is raised to the power of its position > (counted-map expt '(3 2 -4)) ; 3^0, 2^1, (-4)^2 '(1 2 16)

You'll need an interface procedure here, so that each recursive call can know the position of the current item. - Write a structurally recursive function
that takes two arguments:`(is-declared? v exp)``v`, a symbol, and`exp`, an expression in our little language:<exp> ::= <varref> | (lambda (<var>) <exp>) | (<exp> <exp>)

returns true if`is-declared?``v`is declared anywhere in`exp`, and false otherwise. Recall (1) that only a`lambda`expression can declare a variable and (2) that a`lambda`expressions 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? 'y '(f (lambda (y) x))) #t > (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? lambda->param lambda->body app? app->proc app->arg