; CSC151, Class 30: Higher-Order Procedures/Procedures as Values
;
; Overview:
; * A group task
; * Quick reflection
; * Lab
;
; Notes:
; * Read "More higher-order procedures"
; * Think about finishing today's lab outside of class
; * Extra credit for attending Marlene Zuk talks
;
; The Three Problems:
; * Given a list of numbers, count how many are odd.
; * Given a list of values, count how many are numbers.
; * Given a list of numbers, count how many are at least 90.
(define number-of-odd
(lambda (lst)
(if (null? lst)
0
(+ (modulo (car lst) 2)
(number-of-odd (cdr lst))))))
(define count-numbers
(lambda (lst)
(cond
((null? lst) 0)
((number? (car lst)) (+ 1 (count-numbers (cdr lst))))
(else (count-numbers (cdr lst))))))
(define at-least-90
(lambda (lst)
(cond
((null? lst) 0)
((>= (car lst) 90) (+ 1 (at-least-90 (cdr lst))))
(else (at-least-90 (cdr lst))))))
; Common programming technique: Identify repeated *patterns*
; of procedures, so that in the future, you can just copy and
; paste the pattern and fill in the details.
(define count-XXX
(lambda (lst)
(cond
((null? lst) 0)
((TEST? (car lst)) (+ 1 (count-XXX (cdr lst))))
(else (count-XXX (cdr lst))))))
; In Scheme, you can fail sarcastic students.
; In Scheme, you can write these patterns as procedures
(define count
(lambda (test? lst)
(cond
((null? lst) 0)
((test? (car lst)) (+ 1 (count test? (cdr lst))))
(else (count test? (cdr lst))))))
; Cool side-effect of having defined count
; Suppose we need count-odd
; (1) Remember to use (count odd? ...)
; (2) Define it using count
(define count-odd
(lambda (lst)
(count odd? lst)))
(define better-non
(lambda (lst)
(count number? lst)))
; Key morals:
; (1) procedures can take other procedures as parameters
; (2) doing so is useful
; Related point: You don't always need to name procedures
; Unnamed procedure are called anonymous
; Look, you can return procedures, too!
(define make-counter
(lambda (pred?)
(letrec ((counter
(lambda (lst)
(cond
((null? lst) 0)
((pred? (car lst)) (+ 1 (counter (cdr lst))))
(else (counter (cdr lst)))))))
counter)))