【发布时间】:2013-04-08 07:15:50
【问题描述】:
如何重命名 elisp 宏?更准确地说,我想让defun 成为cl-defun 的同义词。
我不关心时间或内存开销。
【问题讨论】:
如何重命名 elisp 宏?更准确地说,我想让defun 成为cl-defun 的同义词。
我不关心时间或内存开销。
【问题讨论】:
我不认为你能做到这一点 - 至少不容易。
由于cl-defun 扩展为defun,如果您执行明显的(defalias 'defun 'cl-defun),则在使用defun 时将获得无限宏扩展循环。
所以你需要做的是
保存原来的defun:(fset 'defun-original (symbol-function 'defun))。
复制cl-macs.el中cl-defun的定义,将defun替换为defun-original。
将defun 替换为cl-defun 使用defalias: (defalias 'defun 'cl-defun)。
现在,至少,如果出现问题,您可以使用(fset 'defun (symbol-function 'defun-original)) 恢复原始行为。
但是,我认为您并不真的想要这样做。
如果你想使用 Common Lisp,useit。试图假装你可以把 Elisp 变成 CL 只会让你伤心。 15 年前我曾尝试过那条路——那里没有乐趣。现在应该更容易了,至少有词法绑定,但我仍然认为这不值得。
如果你想扩展Emacs,那么使用cl-defun 就更没有意义了:你的扩展对其他人毫无用处,你甚至无法寻求帮助,因为很少有人会为这样的激进而烦恼改变这样一个基本功能以获得如此微小的收益。
【讨论】:
cl-defun 扩展没有用? cl-macs.el 是 Emacs 的官方部分。
defun 重新定义为cl-defun!
一般来说,您可以非常简单地使用(defalias 'foo 'cl-defun) 来制作同义词。
但是对cl-defun 的调用的扩展使用defun,所以如果你这样做(defalias 'defun 'cl-defun) 你会陷入无限循环。
您可以通过将defun 替换为一个宏来获得您想要的东西,该宏可以执行defun 的功能或cl-defun 的功能,具体取决于cal 是否使用cl-defun 功能。例如。使用advice-add(位于 Emacs 的后备箱中;您可以在旧版 Emacsen 中使用 defadvice 来获得类似的结果)它可能类似于下面未经测试的代码:
(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 定义的。
【讨论】: