(define left-section (lambda (binary-proc arg1) (lambda (arg2) (binary-proc arg1 arg2)))) ; (sum (list 1 2 3)) ; => ((left-section apply +) (list 1 2 3)) ; => ((lambda (lst) (apply + lst)) (list 1 2 3)) ; => (apply + (list 1 2 3)) ; => (+ 1 2 3) ;;; Procedure: ;;; iota ;;; Parameters: ;;; n, a non-negative integer ;;; Purpose: ;;; Compute a list of the integers in the range [0 .. n). ;;; Produces: ;;; range, a list of integers. (define iota (lambda (n) ; kernel: Compute the list [val .. n) (let kernel ((val 0)) (if (>= val n) null (cons val (kernel (+ val 1))))))) ;;; Procedure: ;;; sum ;;; Parameters: ;;; lst, a "proper list" ;;; Purpose: ;;; Adds all the numbers in lst. ;;; Produces: ;;; result, a number ;;; Preconditions: ;;; lst contains only numbers. ;;; Postconditions: ;;; If lst is null, result is 0. (define sum (left-section apply +)) ;;; What other things might we write? (define disjunction (lambda (pred1? pred2?) (lambda (x) (or (pred1? x) (pred2? x))))) (define conjunction (lambda (pred1? pred2?) (lambda (x) (and (pred1? x) (pred2? x))))) (define negation (lambda (pred?) (lambda (x) (not (pred? x))))) ;;; Procedure: ;;; all- ;;; Parameters: ;;; pred? ;;; Produces: ;;; all-pred?, a procedure from lists to boolean values ;;; Postcnditions: ;;; (all-pred? lst) holds if pred? holds on all elements of list (define all- (lambda (pred?) (letrec ((all-pred? (lambda (lst) (or (null? lst) (and (pred? (car lst)) (all-pred? (cdr lst))))))) all-pred?))) (define all-real? (all- real?)) (define silly (lambda (x) (display x) (newline) x)) (define sum (lambda (lst) (letrec ((kernel (lambda (remaining result) (if (null? remaining) result (kernel (cdr remaining) (+ result (car remaining))))))) (kernel (cdr lst) (car lst))))) ;;; Procedures: ;;; make-remover ;;; remove ;;; Parameters: ;;; pred?, a unary predicate ;;; Purpose: ;;; Build a procedure that removes values from a list. ;;; Produces: ;;; remover, a procedure ;;; Preconditions: ;;; [None] ;;; Postconditions: ;;; remover takes a list as a parameter. ;;; Each element of that list must be a valid parameter of pred? ;;; (remover lst) consists of only the elements of lst for which ;;; pred? does not hold. (define make-remover (lambda (pred?) (letrec ((remover (lambda (ls) (cond ((null? ls) null) ((pred? (car ls)) (remover (cdr ls))) (else (cons (car ls) (remover (cdr ls)))))))) remover))) (define remove make-remover) (define member? (lambda (val lst) (not (not (member val lst))))) (define generate-list (lambda (proc n) (map proc (iota n)))) (define generate-lister (lambda (proc) (lambda (n) (map proc (iota n))))) (define bad-adjectives (list 'grody 'sweet 'awesome)) (define remove-bad-adjectives (make-remover (lambda (lst) (member (car lst) bad-adjectives)))) (define right-section (lambda (proc right) (lambda (left) (proc left right)))) ; The intersection of two lists is a list containing only the values ; that appear in both lists. Define intersection using remove, ; member, intersect, and right-section. (define intersection (lambda (lst1 lst2) ; Strategy: Remove elements in list 1 that don't appear in lst2. ((remove ; "That do NOT appear in list 2" (negation ; "That do appear in list 2" (right-section member lst2))) lst1) ))