views:

115

answers:

1

Suppose I have a single element, and I have a list of predicates (functions). I want to apply each of these predicates to the single element and get a corresponding list of return values. I know that map and friends can apply a single function to each a list of arguments, but is there any concise syntax to apply many functions to a single argument?

Of course I can do

(mapcar (lambda (pred) (funcall pred SINGLE-ELEMENT)) LIST-OF-PREDICATES)

but it would be nice if there was a function that worked like:

(test-predicates-against-element LIST-OF-PREDICATES SINGLE-ELEMENT)

Obviously I can just defun it, but I wanted to know if there is an accepted method for doing this.

+7  A: 

This operation is not that common and there is not really a predefined way to do it, other than writing it directly, in Common Lisp. Various people like a short syntax and added syntactic elements that would help in such a case to all kinds of Lisps. In Common Lisp one might want to write a function that does what you want (instead of adding syntax).

(defun fmap (functions &rest args)
  (declare (dynamic-extent args))
  "Applies each function to the arguments. Returns a list of results."
  (mapcar (lambda (function)
            (apply function args))
          functions))

CL-USER 1 > (fmap (list #'+ #'- #'* #'/) 42 17)
(59 25 714 42/17)
Rainer Joswig
I don't understand what CLHS has to say about what DYNAMIC-EXTENT does. The entry says that, as an example, an implementation may choose to stack allocate variables declared thusly, and shows that it's probably not useful to stack allocate the parameters of a defun. It works here because args is a list (so of known size)?
Frank Shearar
args is a list. This list is only used inside this function and not returned. Thus the dynamic extent. The list can be stack allocated, if that's supported. The list will be destroyed upon returning from this function, thus no GC time is needed.
Rainer Joswig