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.