Say there is a function F. I want to pass a list of functions as an argument into function F.
Function F would go through each function in the list one by one and apply each one to two integers: x and y respectively.
For example, if the list = (plus, minus, plus, divide, times, plus) and x = 6
and y = 2
, the output would look like this:
8 4 8 3 12 8
How do I implement this in common Lisp?
There are many possibilities.
CL-USER> (defun f (x y functions)
(mapcar (lambda (function) (funcall function x y)) functions))
F
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+))
(8 4 8 3 12 8)
CL-USER> (defun f (x y functions)
(loop for function in functions
collect (funcall function x y)))
F
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+))
(8 4 8 3 12 8)
CL-USER> (defun f (x y functions)
(cond ((null functions) '())
(t (cons (funcall (car functions) x y)
(f x y (cdr functions))))))
F
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+))
(8 4 8 3 12 8)
CL-USER> (defun f (x y functions)
(labels ((rec (functions acc)
(cond ((null functions) acc)
(t (rec (cdr functions)
(cons (funcall (car functions) x y)
acc))))))
(nreverse (rec functions (list)))))
F
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+))
(8 4 8 3 12 8)
CL-USER> (defun f (x y functions)
(flet ((stepper (function result)
(cons (funcall function x y) result)))
(reduce #'stepper functions :from-end t :initial-value '())))
F
CL-USER> (f 6 2 (list #'+ #'- #'+ #'/ #'* #'+))
(8 4 8 3 12 8)
And so on.
The first two are readable, the third one is probably how a rookie in a first Lisp course would do it, the fourth one is still the rookie, after he heard about tail call optimization, the fifth one is written by an under cover Haskeller.