如何重命名 elisp 宏?更准确地说,我想让 makedefun
成为cl-defun
. 我不关心时间或内存开销。
3 回答
概括
我不认为你能做到这一点——至少不容易。
由于cl-defun
展开为,如果您执行明显的操作defun
,您将在使用时获得无限宏展开循环。defun
(defalias 'defun 'cl-defun)
是一种方式...
所以你需要做的是
保存原文
defun
:(fset 'defun-original (symbol-function 'defun))
。复制
cl-defun
in的定义cl-macs.el
,替换defun
为defun-original
.替换
defun
为cl-defun
使用defalias
:(defalias 'defun 'cl-defun)
。
现在,至少,如果事情变糟了,您可以使用(fset 'defun (symbol-function 'defun-original))
.
...但你不想要它
但是,我认为您并不想这样做。
如果您想使用 Common Lisp,请使用 它。试图假装你可以把 Elisp 变成 CL 只会让你伤心。15 年前我曾尝试过那条路——那里没有乐趣。现在应该更容易了,至少有词法绑定,但我仍然认为这不值得。
如果你想扩展Emacs
,那么使用cl-defun
就更没有意义了:你的扩展对其他人来说毫无用处,你甚至无法寻求帮助,因为很少有人会为这样一个基本功能的如此彻底的改变而烦恼。微薄的收获。
一般来说,你可以很简单地用(defalias 'foo 'cl-defun)
. 但是对cl-defun
uses的调用的扩展defun
,所以如果你这样做(defalias 'defun 'cl-defun
) 你会进入无限循环。
您可以通过替换defun
一个宏来获得您想要的东西,该宏可以做什么defun
或做什么cl-defun
,具体取决于 cal 是否使用cl-defun
功能。例如使用advice-add
(在 Emacs 的主干中;您可以defadvice
在旧版 Emacsen 中使用以获得类似的结果)它可能看起来像下面未经测试的代码:
(defun my-defun-dispatch (doit name args &rest body)
(let ((needs-cl nil))
(dolist (arg args)
(unless (and (symbolp arg)
(or (not (eq ?& (aref (symbol-name arg) 0)))
(memq arg '(&optional &rest))))
(setq needs-cl t)))
(if needs-cl
`(cl-defun ,name ,args ,@body)
(funcall doit name args body))))
(advice-add :around 'defun 'my-defun-dispatch)
有什么特别的原因吗?
也许这样做是安全的,我相信这是可能的,但我很怀疑如果你不知道如何去做,你应该首先尝试它。我的意思不是任何形式的侮辱。我只是怀疑像这样的根本变化很容易导致问题,所以在尝试之前你应该先对 elisp 有一个扎实的掌握。
我意识到这有点无法回答,但我认为值得一说。
仅供参考cl-defun
是根据defun
.