gpt4 book ai didi

macros - 宏发出 : Eval of a macro body works, 但宏没有

转载 作者:太空宇宙 更新时间:2023-11-03 18:50:05 24 4
gpt4 key购买 nike

考虑以下代码片段:

[1]> (defvar *clist* '((2 1 21) ( 3 2 32) (4 3 43)))
*CLIST*
[2]> (eval `(case '1 ,@(mapcar #'rest *clist*)))
21
[3]> (defmacro tester (index clist)
`(case ,index ,@(mapcar #'rest clist)))
TESTER
[4]> (tester '1 *clist*)
*** - MAPCAR: A proper list must not end with *CLIST*
The following restarts are available:
ABORT :R1 Abort main loop
Break 1 [5]>

代码包含生成的错误消息。
可以清楚地看到,用作正文的代码的 evaltester ,给出结果。但是相同的代码(通过替换*clist* and '1, by clist and index variables.) 在用作时不起作用宏的主体。

最佳答案

测试时backquote , 只需打印它:

> `(case '1 ,@(mapcar #'rest *clist*))
(CASE '1 (1 21) (2 32) (3 43))

在测试宏时,您评估它们(无论是在 REPL 还是在所有更是如此,使用 eval明确地)。

您使用 macroexpand 展开宏并检查代码。

例如,

> (macroexpand-1 '(tester '1 *clist*))
*** - MAPCAR: A proper list must not end with *CLIST*

这告诉您 tester 传递了 symbol *CLIST* 而不是它对 mapcar 的值(value)。

你需要考虑你正在尝试做的事情 "compile-time"对比"execution time" .

  • 你知道编译时的索引吗?
  • 你知道编译时的clist吗?

在您的情况下,没有理由使用 case:

(defmacro tester (index clist) `(third (find ,index ,clist :key #'second)))
(macroexpand-1 '(tester 1 *clist*))
==> (THIRD (FIND 1 *CLIST* :KEY #'SECOND)) ; T
(tester 1 *clist*)
==> 21

因为在编译时你不知道 clist(只有它存储的变量名称),有使用 case 没有好处 - 它必须在编译时知道所有子句。

关于macros - 宏发出 : Eval of a macro body works, 但宏没有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44458239/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com