Function COMPOSE Syntax: compose &rest functions => composite-function Arguments and Values: functions---a list of designators for functions. composite-function---a function created by composing functions. Description: compose returns a function which is created by composing functions right-associatively.
;; Just to illustrate order of operations (defun 2* (x) (* 2 x)) (funcall (compose #'1+ #'1+) 1) => 3 (funcall (compose '1+ '2*) 5) => 11 (funcall (compose #'1+ '2* '1+) 6) => 15
(defun compose (&rest functions) "Compose FUNCTIONS right-associatively, returning a function" #'(lambda (x) (reduce #'funcall functions :initial-value x :from-end t)))
This implementation is fairly straightforward, but very inefficient. In my benchmarks, I found it to be orders of magnitude slower than writing out an equivalent lambda function. However, a compiler macro speeds up some common cases immensely:
;; Converts calls to COMPOSE to lambda forms with everything written ;; out and some things written as direct function calls. ;; Example: (compose #'1+ #'2* #'-) => (LAMBDA (X) (1+ (2* (- X)))) (define-compiler-macro compose (&rest functions) (labels ((sharp-quoted-p (x) (and (listp x) (eql (first x) 'function) (symbolp (second x))))) `(lambda (x) ,(reduce #'(lambda (fun arg) (if (sharp-quoted-p fun) (list (second fun) arg) (list 'funcall fun arg))) functions :initial-value 'x :from-end t))))
This compiler macro shouldn't be considered part of the reference implementation, but it may be useful anyway. I, Peter Scott, place this code in the public domain.
This version allows composition of functions with multiple arguments and return values.
(defun compose2 (f1 f2) (lambda (&rest args) (multiple-value-call f1 (apply f2 args)))) (defun compose (&rest functions) (if functions (reduce #'compose2 functions) #'values))
Alexandria contains this function.(likely nonexhaustive)