;;; Procedure:
;;; compose
;;; Parameters:
;;; f, a procedure
;;; g, a procedure
;;; Purpose:
;;; Functionally compose f and g.
;;; Produced Value:
;;; h, a new procedure
;;; Preconditions:
;;; f must be a unary procedure (only one parameter)
;;; g must be a unary procedure (only one parameter)
;;; The range of g must be a subset of the domain of f
;;; Postconditions:
;;; (h x) = (f (g x))
;;; h is a unary procedure (you should know what that means by now)
;;; domain of h is the domain of g
;;; range of h is the range of f
(define compose
(lambda (f g) ; Params to compose
(lambda (x) ; Params to functions you're building
(f (g x)))))
;;; Some fun functions to compose
(define square (lambda (x) (* x x)))
(define successor (lambda (x) (+ x 1)))
; Return a procedure that holds when *both* p1 and p2 hold.
(define both
(lambda (p1 p2)
(lambda (x)
(and (p1 x) (p2 x)))))
; A goal: Combine unary predicates
(define odd-number? (and integer? odd?))
(define odd-num? (both integer? odd?))
; Good computer scientists also define negate and either