Functional Problem Solving (CSC 151 2014F) : EBoards

CSC 151: Extra Session 11 (Thursday, 20 Nov. 2014)


Overview

About the Quiz

What's on the quiz?

Association lists

Analysis - counting steps (likely morals from the lab)

Higher-order procedures

Random

Potential evil quiz question: "You've now seen two procedures that call assoc and do something with the result. That's clearly now an opportunity to write a higher-order procedure to summarize that. Write (assoc-then-process val lst fun) that follows the model of color-attributes and get-named-color, in that it first finds val in lst and then calls fun on the result.

No, you can't just use compose because assoc may return #f.

More of the same standard model: Fill in the blanks, explain what the code does, write simple procedure that follows a pattern, translate badly-named procedures.

Your questions on recent topics

Tell us more about association lists.

I think of association lists as tables (or table-like).

    FirstName       LastName        Tutorial        ProspectiveMajor
    Fred            Smith           Stone           Quantitative
    Richard         Smith           Hernandez       CS
    Samantha        Smith           French          Unknown
    Y               Smith           Herold          BioComputing
    Sammy           Smith           Stone           Ranting

In Scheme

    (list
     (list "Fred" "Smith" "Stone" "Quantitative")
     (list "Richard" "Smith" "Hernandez" "CS")
     (list "Samantha" "Smith" "French" "CS")
     (list "Y" "Smith" "Herold" "BioComputing"))

Most common activity with tables: Look up something by a "key". For association lists, we assume the key is the first value in the element list (FirstName in the example above).

In Scheme, (assoc key lst), it looks through a list like the one above (an association list) for the first entry that has a matching key.

In early versions of Scheme, association lists were used to implement define. (Also let.)

Since we know recursion, we can implement assoc and also variants thereof.

What's the difference between apply and map?

apply applies the function to all of the elements in the list as whole. map applies the function each element separately.

Does apply apply the function to the list or to the elements of the list or?

(apply + (list 4 1 76)) should be interpreted as (+ 4 1 76) rather than as (+ (list 4 1 76)). The latter doesn't make sense, and we could also write it directly. apply is for the situation in which you've already made the list and want to apply a function.

Example "Sum the elements from 1 to 100, pretend you've never heard of Gauss." (apply + (cdr (iota 101)))

How do we write find-all-objects?

Should I use direct recursion or a kernel? kernel: I like them. We need to keep track of a list, so a kernel is nice to keep track of the accumulated values. Direct recursion: I find it easier to think about. Sam's experience: If I want the values in the same order, kernels get in the way (or at least the traditional kernels), and I'm not doing precondition checking.

(define find-all-objects
  (lambda (key objects)
    (cond
      ; If there are no objects, we certainly can't find anything
      [(null? objects)
       null]
      ; If the first object matches, we want to keep it and then
      ; find any remaining objects
      [(equal? key (caar objects))
       (cons (car objects) (find-all-objects key (cdr objects)))]
      ; If the first object doesn't match, throw away the first
      ; one and keep looking
      [else
       (find-all-objects key (cdr objects))])))

How do we decide where to count when we analyze? Why do we have counter-count!?

Extended example not recorded.

Do you really use "fun" to mean "function" and not "something fun"?

No comment.

Sample quiz questions

Write (assoc-then-process val lst fun) that follows the model of lookup-attributes and get-named-color, in that it first finds val in lst and then calls fun on the result.

   (define lookup-attributes
     (lambda (name lst)
       (let [(assoc-result (assoc name lst))]
         (if assoc-result
             (list-drop assoc-result 4)
             #f))))

   (define lookup-attributes
     (lambda (name lst)
       (let [(assoc-result (assoc name lst))]
         (and assoc-result
              (list-drop assoc-result 4)))))

What would you change in order to get the red component? Just the line that reads list-drop.

   (define lookup-????
     (lambda (name lst)
       (let [(assoc-result (assoc name lst))]
         (and assoc-result
              (FUN assoc-result)))))

   (define lookup-and-process
     (lambda (name lst fun)
       (let [(assoc-result (assoc name lst))]
         (and assoc-result
              (fun assoc-result)))))

Do problem 4 on the lab.

See above.