Exam 2

Recursive Programming Techniques


CS 3540
Programming Languages and Paradigms
Spring Semester 2018


Tuesday, February 27 @ 1:05 PM


Instructions



Exercises


  1. Write a structurally recursive function (merge less-than? lst1 lst2) that merges two sorted lists. lst1 and lst2 are lists of values in the order specified by the less-than? predicate. merge returns a single sorted list containing all the values in 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")
    

  2. Write a mutually-recursive function (nlist-add1 nlst) that takes an n-list as an argument:
                   <n-list> ::= ()
                              | (<number-expression> . <n-list>)
    
        <number-expression> ::= <number> 
                              | <n-list> 
    
    nlist-add1 returns an n-list of the same shape as its argument, but with every number incremented by 1. For example:
         > (nlist-add1 '(1 (4 (9 (16 25)) 36 49) 64))
         '(2 (5 (10 (17 26)) 37 50) 65)
    
    nlist-add1 must be mutually recursive with the function numexp-add1, which increments the numbers in a number expression.

  3. 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)))))
    

  4. Write a structurally recursive function (counted-map f lon) that two arguments, a two-argument function (f item position) and a list of numbers lon:
         <list-of-numbers> ::= ()
                              | (<number> . <list-of-numbers>)
    
    counted-map passes each number in the list to f along with its 0-based position in the list. So, for
    '(3 2), it would evaluate (f 3 0) and (f 2 1). counted-map returns a list of the results. For example:
           ; 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.

  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 (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
    


Eugene Wallingford ..... wallingf@cs.uni.edu ..... February 27, 2018