gpt4 book ai didi

macros - 我可以在 emacs lisp 宏中放置条件吗?

转载 作者:行者123 更新时间:2023-12-01 15:53:30 26 4
gpt4 key购买 nike

如何实现这样的目标?

(defmacro mood (x)
(if (equal (symbol-name x) "t")
`(defun happy ()
(message "Happy"))
`(defun sad ()
(message "Sad")))
)

我的目标是根据参数创建不同的函数。这样做有什么问题吗?

最佳答案

编辑 2:您是对的 - 对于在扩展时评估的代码完全依赖(未评估的)宏的值的情况参数,我相信根据这些参数有条件地生成宏的返回形式是安全的。

您只需要注意,任何以动态 值为条件的行为都需要作为扩展形式的一部分进行处理。

(例如,如果宏参数是一个变量,并且您正在测试条件中的变量值,那么在扩展时进行该测试是不安全的,因为该值是宏的扩展时间和计算扩展代码的时间之间可能会有所不同。)

所以你问题中的具体例子确实是安全的,因此在这种情况下我的变化(下面)实际上不是必需的。然而,扩展时间评估肯定是您通常需要谨慎对待的事情。

初始答案如下...


宏在编译时展开。 (或者在最新版本的 Emacs 中,如果没有可用的字节编译版本的库,它们通常会在加载时“急切地”编译)。

在这些情况下,任何不属于由宏返回的形式的代码在每个 session 中最多被评估一次,但很可能永远对于给定的代码扩展(而扩展后的代码可能会被多次调用)。

如果您需要扩展代码在运行时有条件地执行操作,则条件必须是宏返回的表单的一部分。

编辑:例如,我想您实际上想写的更像是:

(defmacro mood (x)
`(if (equal (symbol-name ,x) "t")
(defun happy ()
(message "Happy"))
(defun sad ()
(message "Sad"))))

尽管您(几乎)永远不想通过比较符号的 symbol-name 来比较符号。您已经假设宏参数将计算为符号,因此只需将符号直接与 eq 进行比较:

(defmacro mood (x)
`(if (eq ,x t)
(defun happy ()
(message "Happy"))
(defun sad ()
(message "Sad"))))

例如,(mood 'foo) 扩展为(由 M-x pp-macroexpand-last-sexp 提供):

(if
(eq 'foo t)
(defun happy nil
(message "Happy"))
(defun sad nil
(message "Sad")))

关于macros - 我可以在 emacs lisp 宏中放置条件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34973029/

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