如何重命名elisp宏?更准确地说,我想让defun成为cl-defun的同义词。我不关心时间和内存开销。
发布于 2013-04-08 21:32:35
摘要
我不认为你能做到这一点--至少不容易做到。
由于cl-defun扩展为defun,因此如果执行明显的(defalias 'defun 'cl-defun),则在使用defun时将获得无限宏扩展循环。
这是一种..。
所以你需要做的是
(fset 'defun-original (symbol-function 'defun)).
defun:在cl-macs.el中保存cl-defun的定义,使用defun-original.
defun替换cl-defun,使用defalias:defalias替换defun现在,至少,如果事情变得糟糕,您可以使用(fset 'defun (symbol-function 'defun-original))恢复原来的行为。
...but你不想要它
然而,我认为你并不是真的想这么做。
如果您想使用Common Lisp,可以使用use it。试图假装你可以把Elisp变成CL,这只会给你带来悲伤。15年前,我曾尝试过这条路--那里一点乐趣都没有。现在应该更容易了,至少有词汇绑定,但我仍然认为不值得花这么大的力气。
如果您想要扩展Emacs,那么使用cl-defun就更没有意义了:您的扩展对其他人来说将是无用的,您甚至无法寻求帮助,因为很少有人会为如此微小的收益而为如此基本的功能做出如此巨大的改变而烦恼。
发布于 2013-04-08 21:38:26
通常,您可以非常简单地使用(defalias 'foo 'cl-defun)作为同义词。但是对cl-defun的调用的扩展使用了defun,所以如果你使用(defalias 'defun 'cl-defun),你会进入无限循环。
您可能可以通过将defun替换为宏来获得您想要的内容,该宏可以执行defun所做的事情,也可以执行cl-defun所做的事情,这取决于调用是否使用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)发布于 2013-04-08 17:57:39
有什么特别的原因吗?
也许这样做是安全的,我相信这是可能的,但我非常怀疑,如果你不知道如何去做,你是否应该首先尝试它。我的意思并不是说这是一种侮辱;我只是怀疑像这样的根本性改变很容易造成问题,所以在尝试它之前,你应该首先对elisp有一个坚实的控制。
我意识到这有点不着边际,但我认为这是值得一说的。
仅供参考的cl-defun是用defun定义的。
https://stackoverflow.com/questions/15873346
复制相似问题