我想生成代码:(nth 0 x) (nth 1 x) ... (nth n x)
其中x
只是一些变量名,而n
是一些数字。
我正在尝试以下列方式:
(defmacro gen(n)
(loop for i from 1 to n do
`(nth i x))
)
检查它如何扩展:
(print (macroexpand-1 '(gen 5)))
控制台输出为:NIL
。怎么做得好?
答案 0 :(得分:2)
答案 1 :(得分:1)
考虑以下代码的值:
(loop for i from 1 to 5
do `(nth ,i x))
由于没有收集,loop
的返回值为零。如果我们将do
更改为collect
:
(loop for i from 1 to 5
collect `(nth ,i x))
我们看到我们正在某个地方。但是,结果列表实际上并不是有效的Common Lisp代码(并且依赖于在使用宏的环境中存在变量x
。)
目前尚不清楚你想用这些做什么(只是运行它们?它们的副作用是免费的,所以只需将它包裹在progn
感觉有些无用),但你需要利用progn
,list
或类似于列表前面的列表,使其成为有效的代码。
(defmacro gen (n &key (var 'x) (accumulator 'list))
(cons accumulator
(loop for i from 1 to n
collect `(nth ,i ,var))))
这最终给了我们这个宏似乎实际上做了一些接近"有效"。