Here is a version of a macro which creates function calls according to every possable combination of concatination of the symbols in symbol-list as the functions, and every possable concatination of the args. If an atom is applied anywhere, it is included in its place according to the pattern.
Code: Select all
(defmacro funcall-matrix (symbol-list args-list)
(let ((functions (apply #'symbol-matrix symbol-list))
(args (apply #'map-each-to-every args-list)))
(cons 'list
(mapcar #'(lambda (elt)
(cons (car elt) (cadr elt)))
(map-each-to-every functions args)))))
(defun symbol-matrix (&rest symbols)
(mapcar
#'(lambda (symbol-list)
(apply #'symbol-concat symbol-list))
(apply #'map-each-to-every symbols)))
(defun map-each-to-every (&rest atoms-or-lsts)
(labels ((mp (&rest lsts)
(if (cdr lsts)
(apply #'mp
(cons
(apply #'append
(mapcar #'(lambda (each-elt)
(mapcar #'(lambda (every-elt)
(append each-elt (list every-elt)))
(ensure-list (second lsts))))
(ensure-list (first lsts))))
(cddr lsts)))
(first lsts))))
(apply #'mp
(cons (mapcar #'list (ensure-list (car atoms-or-lsts)))
(cdr atoms-or-lsts)))))
(defun symbol-concat (&rest symbols)
(intern
(apply #'string-concat
(mapcar
#'(lambda (elt)
(if (symbolp elt)
(symbol-name elt)
(write-to-string elt)))
symbols))))
(defun ensure-list (elt)
(if (listp elt)
elt
(list elt)))
For example, calling
>(macroexpand '(funcall-matrix ((a b c) - (1 2 3 4)) ((arg-a arg-b) 15 (arg-x arg-y arg-z))))
(LIST (A-1 ARG-A 15 ARG-X) (A-1 ARG-A 15 ARG-Y) (A-1 ARG-A 15 ARG-Z)
(A-1 ARG-B 15 ARG-X) (A-1 ARG-B 15 ARG-Y) (A-1 ARG-B 15 ARG-Z) (A-2 ARG-A 15 ARG-X)
(A-2 ARG-A 15 ARG-Y) (A-2 ARG-A 15 ARG-Z) (A-2 ARG-B 15 ARG-X) (A-2 ARG-B 15 ARG-Y)
(A-2 ARG-B 15 ARG-Z) (A-3 ARG-A 15 ARG-X) (A-3 ARG-A 15 ARG-Y) (A-3 ARG-A 15 ARG-Z)
(A-3 ARG-B 15 ARG-X) (A-3 ARG-B 15 ARG-Y) (A-3 ARG-B 15 ARG-Z) (A-4 ARG-A 15 ARG-X)
(A-4 ARG-A 15 ARG-Y) (A-4 ARG-A 15 ARG-Z) (A-4 ARG-B 15 ARG-X) (A-4 ARG-B 15 ARG-Y)
(A-4 ARG-B 15 ARG-Z) (B-1 ARG-A 15 ARG-X) (B-1 ARG-A 15 ARG-Y) (B-1 ARG-A 15 ARG-Z)
(B-1 ARG-B 15 ARG-X) (B-1 ARG-B 15 ARG-Y) (B-1 ARG-B 15 ARG-Z) (B-2 ARG-A 15 ARG-X)
(B-2 ARG-A 15 ARG-Y) (B-2 ARG-A 15 ARG-Z) (B-2 ARG-B 15 ARG-X) (B-2 ARG-B 15 ARG-Y)
(B-2 ARG-B 15 ARG-Z) (B-3 ARG-A 15 ARG-X) (B-3 ARG-A 15 ARG-Y) (B-3 ARG-A 15 ARG-Z)
(B-3 ARG-B 15 ARG-X) (B-3 ARG-B 15 ARG-Y) (B-3 ARG-B 15 ARG-Z) (B-4 ARG-A 15 ARG-X)
(B-4 ARG-A 15 ARG-Y) (B-4 ARG-A 15 ARG-Z) (B-4 ARG-B 15 ARG-X) (B-4 ARG-B 15 ARG-Y)
(B-4 ARG-B 15 ARG-Z) (C-1 ARG-A 15 ARG-X) (C-1 ARG-A 15 ARG-Y) (C-1 ARG-A 15 ARG-Z)
(C-1 ARG-B 15 ARG-X) (C-1 ARG-B 15 ARG-Y) (C-1 ARG-B 15 ARG-Z) (C-2 ARG-A 15 ARG-X)
(C-2 ARG-A 15 ARG-Y) (C-2 ARG-A 15 ARG-Z) (C-2 ARG-B 15 ARG-X) (C-2 ARG-B 15 ARG-Y)
(C-2 ARG-B 15 ARG-Z) (C-3 ARG-A 15 ARG-X) (C-3 ARG-A 15 ARG-Y) (C-3 ARG-A 15 ARG-Z)
(C-3 ARG-B 15 ARG-X) (C-3 ARG-B 15 ARG-Y) (C-3 ARG-B 15 ARG-Z) (C-4 ARG-A 15 ARG-X)
(C-4 ARG-A 15 ARG-Y) (C-4 ARG-A 15 ARG-Z) (C-4 ARG-B 15 ARG-X) (C-4 ARG-B 15 ARG-Y)
(C-4 ARG-B 15 ARG-Z))
I remeber when I started programming in Lisp, I was comming from Java and implemented a simple OO system. Its funny how influneced you are by the languages you use.