; brussell 6.001 Tutorial 4, Spring 2004

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Upcoming deadlines:

; Quiz I: Tuesday, 3/2 7-9pm
; Lecture 9, 3/4 (LIVE) 10am
; Pset 4: Tuesday, 3/9 midnight

; For Quiz I review material, look at "records of previous
; terms" link on course webpage.

; Questions?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Objectives: 
; Higher order procedures, types, data abstraction, quiz review

; Details:
; map, fold-right, filter, some trees

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Higher order procedures (map, filter, fold-right)

; Example 1.1
; Deep-reverse

(define (deep-reverse lst)
  (if (or (null? lst) (leaf? lst))
      lst
    (map deep-reverse (reverse lst))))

; Example 1.2
; Iterative reverse

(define (reverse lst)
  (define (helper lst new)
    (if (null? lst) new
      (helper (cdr lst) (cons (car lst) new))))
  (helper lst nil))

; Examples 2-4
; Class list

(define class-list
  (list (list "Molly" 98 86 91 88)
	(list "Tom" 95 81 92 86)
	(list "Mr. Pickles" 56 62 61 55)))

; Example 2
; Get all pset1 scores

(map (lambda (x) (cadr x)) class-list)

; Example 3
; Get all people who scored lower than a 70 on pset2

(filter (lambda (x) (< (caddr x) 70)) class-list)

; Example 4
; Compute the mean grade for each student

(map (lambda (x)
       (list (car x)
	     (/ (fold-right + 0 (cdr x)) (length x))))
     class-list)

; Example 5
; Write a procedure that negates the output value of a procedure 
; of one argument

(define (negation p)
  (lambda (x)
    (not (p x))))

; Example 6
; Create all subsets of a list, i.e. (1 2 3) has subsets
; (() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))

(define (subsets s)
  (if (null? s) (list nil)
    (let ((rest (subsets (cdr s))))
      (append rest 
	      (map (lambda (x) (cons (car s) x)) rest)))))

; Example 7
; Flatten, i.e. enumerate tree

(define (flatten tree)
  (cond ((null? tree) tree)
	((leaf? tree) (list tree))
	(else (append (flatten (car tree))
		      (flatten (cdr tree))))))

; Example 8
; Sum odd squares of tree:

(define (sum-odd-squares tree)
  (fold-right + 0
	      (map square
		   (filter odd? (flatten tree)))))

; Example 9
; Define map in terms of fold-right

(define (map proc lst)
  (fold-right (lambda (x y) (append (list (proc x))
				    y)) 
	      nil lst))

; Example 10
; fold-left

(define (fold-left op init lst)
  (define (iter result rest)
    (if (null? rest) result
      (iter (op result (car rest))
	    (cdr rest))))
  (iter init lst))

; Example 5
; list-ref
(define (list-ref lst i)
  (if (= i 0) (car lst)
    (list-ref (cdr lst) (- i 1))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Types:

; Example 1

((lambda (x + y)
   (+ x y)) 3 * 4)
; Value: 12
; Type: number

; Example 2

(let ((* /)
      (/ *))
  (/ 12 (* 6 3)))
; Value: 24
; Type: number

; Example 3

((lambda (n)
   (lambda (x) (expt x n)))
 5)
; Value: Compound-procedure
; Type: number->number

; Example 4
(define foo ((lambda (x)
	       (lambda (y) (y x))) 
	     (lambda () 5)))
; Value: unspecified
; Type: unspecified

; Example 5
foo
; Value: Compound-procedure
; Type: (nil->number)->A

; Example 6
(foo (lambda (z) (+ (z) 1)))
; Value: 6
; Type: number

; Example 7
(define plus (lambda () +))
((lambda (x y) (y x 2)) 2 plus)
; Value: error

; Example 8
((lambda (x y) ((y) x 2)) 2 plus)
; Value: 4
; Type: number

; Example 9
((lambda (arg) ARG) (lambda () 5))
; Value: Compound-procedure
; Type: nil->number

; Example 10
(lambda (a)
  (lambda (b)
    (/ (+ a b) (- a b))))
; Value: Compound-procedure
; Type: number->(number->number)

; Example 11
(define (plus x y) (+ x y))
(lambda (a)
  (lambda (b)
    (a b plus)))
; Value: Compound-procedure
; Type: (A,(number,number->number)->B)->(A->B)

; Example 12
(lambda (a)
  ((a) plus 5))
; Value: Compound-procedure
; Type: (nil->((num,num->num),num->A))->A

; Example 13
(define chair (make-chair)) ; Type: chair
(lambda (a)
  (a #t chair))
; Value: Compound-procedure
; Type: (boolean,chair->A)->A

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Misc procedures

(define (map f lst)
  (if (null? lst)
      nil
    (cons (f (car lst))
          (map f (cdr lst)))))

(define (filter pred lst)
  (cond ((null? lst) nil)
	((pred (car lst))
	 (append (car lst)
		 (filter pred (cdr lst))))
	(else (filter pred (cdr lst)))))

(define (fold-right op init lst)
  (if (null? lst) 
      init
    (op (car lst) (fold-right op init (cdr lst)))))

