ARNESI
(defun compose (f1 &rest functions)
"Returns a function which applies the arguments in order.
(funcall (compose #'list #'+) 1 2 3) ==> (6)"
(case (length functions)
(0 f1)
(1 (lambda (&rest args)
(funcall f1 (apply (car functions) args))))
(2 (lambda (&rest args)
(funcall f1
(funcall (first functions)
(apply (second functions) args)))))
(3 (lambda (&rest args)
(funcall f1
(funcall (first functions)
(funcall (second functions)
(apply (third functions) args))))))
(t
(let ((funcs (nreverse (cons f1 functions))))
(lambda (&rest args)
(loop
for f in funcs
for r = (multiple-value-list (apply f args))
then (multiple-value-list (apply f r))
finally (return r)))))))
(defun conjoin (&rest predicates)
(case (length predicates)
(0 (constantly t))
(1 (car predicates))
(2 (lambda (&rest args)
(and (apply (first predicates) args)
(apply (second predicates) args))))
(3 (lambda (&rest args)
(and (apply (first predicates) args)
(apply (second predicates) args)
(apply (third predicates) args))))
(t
(lambda (&rest args)
(loop
for p in predicates
for val = (apply p args)
while val
finally (return val))))))
(defun curry (function &rest initial-args)
"Returns a function which will call FUNCTION passing it
INITIAL-ARGS and then any other args.
(funcall (curry #'list 1) 2) ==> (list 1 2)"
(lambda (&rest args)
(apply function (append initial-args args))))
(defun rcurry (function &rest initial-args)
"Returns a function which will call FUNCTION passing it the
passed args and then INITIAL-ARGS.
(funcall (rcurry #'list 1) 2) ==> (list 2 1)"
(lambda (&rest args)
(apply function (append args initial-args))))
(defun noop (&rest args)
"Do nothing."
(declare (ignore args))
(values))
(defmacro lambda-rec (name args &body body)
"Just like lambda except BODY can make recursive calls to the
lambda by calling the function NAME."
`(lambda ,args
(labels ((,name ,args ,@body))
(,name ,@args))))
(defun y (lambda)
(funcall (lambda (f)
(funcall (lambda (g)
(funcall g g))
(lambda (x)
(funcall f
(lambda ()
(funcall x x))))))
lambda))