Lecture 13: Thou Shall Not Steal Code

###
Lecture 13: Thou Shall Not Steal Code

1. Sorting Numbers:

       ;; sort : list of numbers -> list of numbers
       ;; Purpose: produce a list with the same numbers but sorted
       ;;   in ascending order
       ;; Example: in (list 3 1 2), out (list 1 2 3)
       (define (sort alon)
         (cond
           ((empty? alon) empty)
           ((cons? alon) (insert (first alon) (sort (rest alon))))))

       ;; insert : number list-of-numbers (sorted) -> list-of-numbers
       ;; same numbers as input list and the additional input, sorted
       (define (insert an alon)
         (cond
           ((empty? alon) (cons an empty))
           (else (cond
       	    ((< an (first alon)) (cons an alon))
       	    (else (cons (first alon) (insert an (rest alon))))))))

   Okay, so here is one hint on the pragmatics of `local`:

       ;; sort : list of numbers -> list of numbers
       ;; Purpose: produce a list with the same numbers but sorted
       ;;   in ascending order
       ;; Example: in (list 3 1 2), out (list 1 2 3)
       (define (sort alon)
         (local ((define (sort alon)
       	    (cond
       	      ((empty? alon) empty)
       	      ((cons? alon) (insert (first alon) (sort (rest alon))))))

       	  (define (insert an alon)
       	    (cond
       	      ((empty? alon) (cons an empty))
       	      (else (cond
       		      ((< an (first alon)) (cons an alon))
       		      (else (cons (first alon) (insert an (rest alon)))))))))
           (sort alon)))

   Let's inspect the bindings: where will the meaning for variable occurrences come from?

   Now suppose we want a program that sorts numbers in descending order?

       ;; sort : list of numbers -> list of numbers
       ;; Purpose: produce a list with the same numbers but sorted
       ;;   in descending order
       ;; Example: in (list 3 1 2), out (list 1 2 3)
       (define (sort alon)
         (local ((define (sort alon) ... )

       	  (define (insert an alon)
       	    (cond
       	      ((empty? alon) (cons an empty))
       	      (else (cond
       		      ((> an (first alon)) (cons an alon))
       		      (else (cons (first alon) (insert an (rest alon)))))))))
           (sort alon)))

   There is just one difference: the > must be changed into a <.
2. We should never, ever copy code. When we are tempted to do that, we should instead introduce a program that can do both!

   Here is how we do it:

       (define (sort comparison alon)
         (local ((define (sort alon) ... )

       	  (define (insert an alon)
       	    (cond
       	      ((empty? alon) (cons an empty))
       	      (else (cond
       		      ((comparison an (first alon)) (cons an alon))
       		      (else (cons (first alon) (insert an (rest alon)))))))))
           (sort alon)))

   To do a sort in ascending order, we now use

   - `(sort < alon)` for ascending order
   - `(sort < alon)` for descending order

   Okay -- figure out how to sort a database, using the same old sort function:

   - by descending order of salaries
   - by ascending order of age
   - by descending order of salaries, and within the same salary group by ascending order of age
3. Let's figure out an evaluation proceeds:

         (sort < (list 2 1))
       ;; take body of sort and replace comparison by < and alon by (list 2 1)

       = (local ((define (sort alon)
       	    (cond
       	      ((empty? alon) empty)
       	      ((cons? alon) (insert (first alon) (sort (rest alon))))))

       	  (define (insert an alon)
       	    (cond
       	      ((empty? alon) (cons an empty))
       	      (else (cond
       		      ((< an (first alon)) (cons an alon))
       		      (else (cons (first alon) (insert an (rest alon)))))))))
           (sort (list 2 1)))

       = (sort (list 2 1))

         and add the following to top-level window:

                (define (sort alon)
       	    (cond
       	      ((empty? alon) empty)
       	      ((cons? alon) (insert (first alon) (sort (rest alon))))))

       	  (define (insert an alon)
       	    (cond
       	      ((empty? alon) (cons an empty))
       	      (else (cond
       		      ((< an (first alon)) (cons an alon))
       		      (else (cons (first alon) (insert an (rest alon))))))))

   But which `sort` do we use now?

   The trick is that, right before we lift the local definitions to the "Definitions Window", we rename them systematically and use BRAND NEW names (i.e. names that aren't used for anyone else in the Definitions Window).

   Rename sort and insert above, then finish ...

Matthias Felleisen | This page was generated on Fri Mar 5 09:04:41 CST 1999.