How can I rename elisp macro? To be more accurate, I want make defun
to be synonym to cl-defun
.
I do not care about time or memory overhead.
问题:
回答1:
Summary
I don't think you can do that - at least not easily.
Since cl-defun
expands to defun
, you will get an infinite macroexpand loop when using defun
if you do the obvious (defalias 'defun 'cl-defun)
.
The is a way...
So what you need to do is
save the original
defun
:(fset 'defun-original (symbol-function 'defun))
.copy the definition of
cl-defun
incl-macs.el
, replacingdefun
withdefun-original
.replace
defun
withcl-defun
usingdefalias
:(defalias 'defun 'cl-defun)
.
Now, at least, if things go sour, you can restore the original behavior with (fset 'defun (symbol-function 'defun-original))
.
...but you don't want it
However, I think you don't really want to do that.
If you want to use a Common Lisp, use it. Trying to pretend that you can turn Elisp into CL will cause you nothing but grief. I tried to travel that road 15 years ago - there is no fun there. It should be easier now, at least there is lexical binding, but I still don't think it is worth the effort.
If you want to extend Emacs
, then using cl-defun
makes even less sense: your extensions will be useless for others and you won't even be able to ask for help because few people will bother with such a radical change in such a basic functionality for such a tiny gain.
回答2:
In general, you can make a synonym very simply with (defalias 'foo 'cl-defun)
.
But the expansion of a call to cl-defun
uses defun
, so if you do (defalias 'defun 'cl-defun
) you'll get into infinite loops.
You can probably get what you want by replacing defun
with a macro which either does what defun
does or what cl-defun
does, depending on whether the cal uses cl-defun
features or not. E.g. using advice-add
(which is in Emacs's trunk; you can use defadvice
in older Emacsen to get simlar results) it could look something like the untested code below:
(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)
回答3:
Any particular reason?
Maybe it's safe to do, and I'm sure it's possible, but I'm very dubious that you should be attempting it in the first place if you can't figure out how to go about it. I don't mean that as any kind of insult; I just suspect that a fundamental change like this could easily cause problems, so you ought to have a solid handle on elisp first before trying it.
I realise that's a bit of a non-answer, but I thought it was worth saying.
FYI cl-defun
is defined in terms of defun
.