Is there a way to do something like lexical closures using macrolet? What I want to do is make the following macro a local recursive helper that calls a function on each combination instead of generating a list as it does now calling the macro in the repl results in:
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))
What I would like is a macro that takes a function and any number of lists and results in nested loops that call the function on each combination. I'm pretty new to lisp, this is the first macro I've written beyond 'nif' clones and the like so any suggestions are appreciated.
I've tried to turn the macro into a macrolet in a macro that takes a function and the line '(nreverse (list ,item ,@vars))' is replaced with '(func (nreverse (list ,item ,@vars)))' but I get errors saying that func is an undefined variable or function.
This is the original function:
(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))))))
This is what I've tried with macrolet and get undefined function 'func' errors.
(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)))