for last several weeks I've tried to understand macros, especially their arguments evaluation.
I need such construct in my project:
(n-mapcar #'(lambda ( <variables-list> ) (<and-body-of-function-to-execute>)) '(<over-several-lists-of-arguments>))
Why I call this n-mapcar?
Simply because it acts like applying a lambda function to each element of cartesian product of sets.
For example I would like this function to do following:
(n-mapcar #'(lambda (x y) (* x y)) '((1 2 3) (4 5 6))) --> (4 5 6 8 10 12 12 15 18); or
(n-mapcar #'(lambda (x y z) (sqrt (+ (* x x) (* y y) (* z z)))) '((2 3 5) (7 11 13) (17 19 23))) --> (18.493243 20.34699 24.124676 20.34699 22.045409 25.573424 21.494185 23.10844 26.495284 18.627936 20.46949 24.228083 20.46949 22.15852 25.670996 21.610184 23.216374 26.589472 19.052559 20.856654 24.556059 20.856654 22.51666 25.980763 21.97726 23.558438 26.888659)
and so on ...
I wrote recursive macro to do most of work:
Code: Select all
(defmacro ncr (params form lst)
"ncr wraps form with adequate (mapcan #'(lambda parameter from params) applied to list of arguments from lst"
(let ((p-car (car params))
(p-cdr (cdr params))
(l-cdr (cdr lst))
(l-car (car lst)))
(if (null p-cdr)
`(mapcar #'(lambda (,p-car) ,form) ',l-car)
`(mapcan #'(lambda (,p-car) (ncr ,p-cdr ,form ,l-cdr )) ',l-car))))
Code: Select all
(MAPCAN (FUNCTION (LAMBDA (X)
(MAPCAR (FUNCTION (LAMBDA (Y) (* X Y))) (QUOTE (4 5 6)))))
(QUOTE (1 2 3)))
Code: Select all
(defmacro n-mapcar ((f (l p f)) (q lst))
`(ncr ,p ,f ,lst))
Looks complicated, but works the way I want:
(n-mapcar #'(lambda (x y) (* x y)) '((1 2 3) (4 5 6))) --> (4 5 6 8 10 12 12 15 18)
What is my question?
I would like to pass to the macro not only list itself: '((1 2 3)(4 5 6)), but also a variable (setf thelist '((9 8 7)(6 5 4)(3 2 1)))
(n-mapcar #'(lambda (x y z) (* x y z)) thelist)
and I tried hundred different ways and can't do that.
The ncr macro must stay as is because it makes recursive nesting of mapcans and mapcar, so it's structure should be clear.
It seems there is a need for another macro which passes arguments to ncr, and part of them stays unevaluated, and rest part is (lst).
In one of previous experiments I successfully used an EVAL, but all big people (Norvig, Seibel, Graham) suggest to avoid it especially
in such constructs as mine.
Thanks in advance, A.