; Return a function that applies f n times on its parameter. n >= 1.
(define (self-compose* f n)
(cond ((= n 1) f)
((> n 1) (lambda (x) (f ((self-compose* f (- n 1)) x))))
(else (error "self-compose*: n must be an integer larger than 0"))))
; Return a function that applies all functions to each other sequentially. The first function in f-list is applied as the last one.
(define (compose* f-list)
(cond ((= (length f-list) 1)
(car f-list))
((> (length f-list) 1)
(lambda (x) ((car f-list) ((compose* (cdr f-list)) x))))
(else (error "compose* must be applied on a non-empty function list"))))
; Alternative, and more attractive variants:
(define (self-compose* f n)
(cond ((= n 1) f)
((> n 1) (compose f (self-compose* f (- n 1))))
(else (error "self-compose*: n must be an integer larger than 0"))))
(define (compose* fn-lst)
(cond ((= (length fn-lst) 1) (car fn-lst))
((> (length fn-lst) 1)
(compose (car fn-lst) (compose* (cdr fn-lst))))
(else (error "compose* must be applied on a non-empty function list"))))
(define (curry2 f)
(lambda(x)
(lambda(y)
(f x y))))
(define (reduce-right f lst)
(if (null? (cdr lst))
(car lst)
(f (car lst)
(reduce-right f (cdr lst)))))
; An alternative implementation of compose* in terms of compose and reduce-right:
(define (compose* fn-lst) (reduce-right compose fn-lst))
(define compose* ((curry2 reduce-right) compose))
(define (incr n) (+ n 1))
(define (fac n) (if (= n 0) 1 (* n (fac (- n 1)))))
(define (compose f g)
(lambda (x) (f (g x))))