Higher-Order Procedures

(map (lambda (x) (* x x)) '(1 2 3 4))          ; (1 4 9 16)
(map list '(1 2 3) '(a b c))                    ; ((1 a) (2 b) (3 c))
(for-each (lambda (x) (display x) (newline)) '(a b))
(vector-map + #(1 2) #(10 20))                  ; #(11 22)
(string-map char-upcase "hi")                   ; "HI"

;; Writing our own higher-order procedures
(define (my-filter pred lst)
  (cond ((null? lst) '())
        ((pred (car lst)) (cons (car lst) (my-filter pred (cdr lst))))
        (else (my-filter pred (cdr lst)))))

(define (fold-left* f init lst)                 ; accumulate from the left
  (if (null? lst) init (fold-left* f (f init (car lst)) (cdr lst))))
(define (fold-right* f init lst)                ; accumulate from the right
  (if (null? lst) init (f (car lst) (fold-right* f init (cdr lst)))))

(fold-left* + 0 '(1 2 3 4))                     ; 10
(fold-right* cons '() '(1 2 3))                 ; (1 2 3) (copy)
(fold-left* (lambda (acc x) (cons x acc)) '() '(1 2 3))   ; (3 2 1) (reverse)

;; Procedures returning procedures
(define (compose . fs)
  (if (null? fs)
      (lambda (x) x)
      (lambda (x) ((car fs) ((apply compose (cdr fs)) x)))))
((compose (lambda (x) (* 2 x)) (lambda (x) 
…