;; The following is a collection of "interesting" functions in the sense ;; that they do unusual things, such as take or return functions as values. ;; ;;********************************************************** ;; the apply function: (apply f a1... bList) ;; simulates the call (f a1 ... (car bList) (cadr bList) ...) ;; Note that there may be no a's (if apply gets only 2 arguments, the last ;; one is assumed to be a list whose arguments become the arguments of f) (apply + '(1 2 3)) ;;gives 6 because (+ 1 2 3) is legal (apply + 1 '(2 3)) ;; also gives 6 because it becomes (+ 1 2 3) (eval (cons '+ '(1 2 3))) ;; also yields the same result ;; (apply length '(1 2 3)) ; will yield error since (length 1 2 3) is illegal (apply length (list (list 1 2 3))) ;;works correctly ;; n-add is a function that returns a function that increments values ;; by its argument, n (define (n-add n) (lambda (x) (+ x n))) (n-add 3) ;; the function that adds 3 to its argument ((n-add 3) 5) ;; applying this function to 5 yields the expected value, 8 ;; zipfn takes two equi-length lists, and applies the functions ;; in the first list to the corresponding element of the second; (define (zipfn fs ys) ;; LIST(B->A) , LIST(B) -> LIST(A) (cond ((null? fs) '()) ((null? ys) '()) ((and (pair? fs) (pair? ys)) (cons (apply (car fs) (list (car ys))) ;;had to "pack up" the arg for apply (zipfn (cdr fs) (cdr ys)) ) ))) (zipfn ;; applies each function on top to the arg below (list (n-add 3) (n-add 5)) (list 7 -2)) ;; -> (10 3) ;; we know (map f ys) applies f to all elements in the list ys; what if we have ;; a list of functions fs, and want to apply each to the same value y? ;; Clearly (map y fs) won't work because y is not a function. But what if we ;; make a function out of y that applies its argument to y? (define (map-fns-to-arg fs y) (map (lambda (g) (g y)) ;; takes the parameter function,g, and calls it on y fs )) (map-fns-to-arg (list (n-add 3) (n-add 6) (n-add -2)) 5) ;;-> (8 11 3)