gpt4 book ai didi

function - 在 dolist 中扩展宏

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

如何在另一个循环宏(如 dolist)中扩展一个向 obarray(此处为 defun)添加符号的宏?例如,

(defmacro make-cmd (cmd &optional search)
"Some function factory."
(let ((fn (intern (concat "fn-" cmd))))
`(defun ,fn (&optional args)
(interactive)
(let ((str (symbol-name ',fn))
,@(when search
'((dir "~"))))
(message "Called %S from %S" str
(or (and (bound-and-true-p dir) dir)
default-directory))))))

;; functions `fn-f1' and `fn-f2' aren't added to obarray
(dolist (x '("f1" "f2"))
`(make-cmd ,x t))

;; works like this
(make-cmd "f1" t)

我希望在编译和遍历函数名时只需要宏。 common-lisp 解决方案可能适合 emacs-lisp。

最佳答案

(其他人已经回答了您的直接问题。但这可能会回答您问题背后的问题并说明您真正想做的事情。如果没有,请查看其他答案。)

根本不需要宏来做您想做的事。只需使用 defaliasfset。每个都是一个函数

(defun foo (cmd &optional search)
(let ((fn (intern (concat "fn-" cmd))))
(defalias fn `(lambda (&optional args)
(let ((str (symbol-name ',fn))
,@(when search
'((dir "~"))))
(message "Called %S from %S" str
(or (and (bound-and-true-p 'dir) dir)
default-directory)))))))

(dolist (x '("f1" "f2")) (foo x))

然后 (symbol-function 'fn-f1) 返回:

(lambda (&optional args)
(let ((str (symbol-name 'fn-f1)))
(message "Called %S from %S" str (or (and (bound-and-true-p dir) dir)
default-directory))))

如果您使用词法绑定(bind)(即,将局部变量绑定(bind) -*- lexical-binding: t -*- 放在文件顶部此代码已定义,那么您不需要任何反引号。例如:

(defun foo (cmd &optional search)
(let ((fn (intern (concat "fn-" cmd))))
(defalias fn (lambda (&optional args)
(let ((str (symbol-name fn))
(dir (if search "~" default-directory)))
(message "Called %S from %S" str dir))))))

(dolist (x '("f1" "f2")) (foo x))

如果这样做,则每个函数 fn-f1fn-f2 都被定义为闭包,如下所示:

(symbol-function 'fn-f1)

(closure
((fn . fn-f1)
(search)
(cmd . "f1")
t)
(&optional args)
(let ((str (symbol-name fn))
(dir (if search "~" default-directory)))
(message "Called %S from %S" str dir)))

并且 (foo "f3":SEARCH) 定义了一个函数 fn-f3(一个闭包),它封装了一个绑定(bind)的其他自由变量 search 到非 nil:SEARCH,这样局部变量 dir 就绑定(bind)到 "~" :

(symbol-function 'fn-f3)

(closure
((fn . fn-f3)
(search . :SEARCH) ;; <==============
(cmd . "f3")
t)
(&optional args)
(let ((str (symbol-name fn))
(dir (if search "~" default-directory)))
(message "Called %S from %S" str dir)))

关于function - 在 dolist 中扩展宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38579435/

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