Есть ли способ сделать что-то вроде лексического замыкания, используя macrolet? Что я хочу сделать, так это сделать следующий макрос локальным рекурсивным помощником, который вызывает функцию для каждой комбинации вместо генерации списка, как это теперь происходит, вызывая макрос в repl, что приводит к:
CL-USER> (combinations nil '(1 2 3) '(4 5 6))
((1 4) (1 5) (1 6) (2 4) (2 5) (2 6) (3 4) (3 5) (3 6))
То, что я хотел бы, это макрос, который принимает функцию и любое количество списков и приводит к появлению вложенных циклов, которые вызывают функцию для каждой комбинации. Я довольно новичок в lisp, это первый макрос, который я написал за пределами клонов 'nif' и т.п., поэтому любые предложения приветствуются.
Я пытался превратить макрос в макроклет в макросе, который принимает функцию, и строка '(nreverse (list, item, @ vars))' заменяется на '(func (nreverse (list, item, @vars))) 'но я получаю ошибки, утверждая, что func - неопределенная переменная или функция.
Это оригинальная функция:
(defmacro combinations (vars &rest lsts)
(with-gensyms (item)
`(loop for ,item in ,(car lsts) ,(if (null (cdr lsts)) 'collecting 'nconcing)
,(if (null (cdr lsts))
`(nreverse (list ,item ,@vars))
`(combinations (,item ,@vars) ,@(cdr lsts))))))
Это то, что я пробовал с макросом и получаю неопределенную ошибку функции 'func'.
(defmacro for-all-combonations (func &rest lst)
(macrolet ((for-all (vars &rest lsts)
(with-gensyms (item)
`(loop for ,item in ,(car lsts) ,(if (null (cdr lsts))
'collecting 'nconcing)
,(if (null (cdr lsts))
`(func (nreverse (list ,item ,@vars)))
`(for-all (,item ,@vars) ,@(cdr lsts)))))))
(for-all nil lst)))