2

如何重命名 elisp 宏?更准确地说,我想让 makedefun成为cl-defun. 我不关心时间或内存开销。

4

3 回答 3

4

概括

我不认为你能做到这一点——至少不容易。

由于cl-defun展开为,如果您执行明显的操作defun,您将在使用时获得无限宏展开循环。defun(defalias 'defun 'cl-defun)

是一种方式...

所以你需要做的是

  1. 保存原文defun(fset 'defun-original (symbol-function 'defun))

  2. 复制cl-defunin的定义cl-macs.el,替换defundefun-original.

  3. 替换defuncl-defun使用defalias: (defalias 'defun 'cl-defun)

现在,至少,如果事情变糟了,您可以使用(fset 'defun (symbol-function 'defun-original)).

...但你不想要它

但是,我认为您并不这样做。

如果您想使用 Common Lisp,请使用 。试图假装你可以把 Elisp 变成 CL 只会让你伤心。15 年前我曾尝试过那条路——那里没有乐趣。现在应该更容易了,至少有词法绑定,但我仍然认为这不值得。

如果你想扩展Emacs,那么使用cl-defun就更没有意义了:你的扩展对其他人来说毫无用处,你甚至无法寻求帮助,因为很少有人会为这样一个基本功能的如此彻底的改变而烦恼。微薄的收获。

于 2013-04-08T13:32:34.613 回答
2

一般来说,你可以很简单地用(defalias 'foo 'cl-defun). 但是对cl-defunuses的调用的扩展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)
于 2013-04-08T13:38:26.363 回答
1

有什么特别的原因吗?

也许这样做是安全的,我相信这是可能的,但我很怀疑如果你不知道如何去做,你应该首先尝试它。我的意思不是任何形式的侮辱。我只是怀疑像这样的根本变化很容易导致问题,所以在尝试之前你应该先对 elisp 有一个扎实的掌握。

我意识到这有点无法回答,但我认为值得一说。

仅供参考cl-defun是根据defun.

于 2013-04-08T09:57:39.173 回答