【发布时间】:2013-09-19 13:11:59
【问题描述】:
我安装的一些 elisp 函数会产生警告:
`flet' is an obsolete macro (as of 24.3); use either `cl-flet' or `cl-letf'.
如果我简单地将所有flet 替换为cl-flet 会不会很危险?
如果可以更换,哪个更好?
如果替换它不危险,我会向项目发送拉取请求。
他们不改变它有什么原因吗?
【问题讨论】:
标签: emacs
我安装的一些 elisp 函数会产生警告:
`flet' is an obsolete macro (as of 24.3); use either `cl-flet' or `cl-letf'.
如果我简单地将所有flet 替换为cl-flet 会不会很危险?
如果可以更换,哪个更好?
如果替换它不危险,我会向项目发送拉取请求。
他们不改变它有什么原因吗?
【问题讨论】:
标签: emacs
flet 与 cl-flet 或 cl-letf 不同。
它更危险(也许更强大)。这就是它被弃用的原因。
既然不一样(动态绑定一个函数名),你就得想想
如果适合将其替换为cl-flet。
flet不能替换为cl-flet的小例子
(defun adder (a b)
(+ a b))
(defun add-bunch (&rest lst)
(reduce #'adder lst))
(add-bunch 1 2 3 4)
;; 10
(flet ((adder (a b) (* a b)))
(add-bunch 1 2 3 4))
;; 24
(cl-flet ((adder (a b) (* a b)))
(add-bunch 1 2 3 4))
;; 10
注意cl-flet 进行词法绑定,所以adder 的行为没有改变,
而flet 进行动态绑定,这使得add-bunch 暂时产生一个阶乘。
【讨论】:
flet的定义,剥离obsolete并将其放入你的.emacs中。删除 flet 而不是你的应该是包编写者的工作。
(setq byte-compile-warnings '(not obsolete))
flet 警告没有重写包 api,我无能为力。
cl-letf 函数可用于动态绑定函数,正如 Artur 在 this 博客条目中所描述的那样。
【讨论】:
您可以修改您的函数以使用lawlist-flet 或创建一个别名——我所做的只是删除警告并将flet 宏重命名为lawlist-flet:
;;;;;;;;;;;;;;;;;;;;;;;;;;;; FLET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defmacro lawlist-flet (bindings &rest body)
"Make temporary overriding function definitions.
This is an analogue of a dynamically scoped `let' that operates on the function
cell of FUNCs rather than their value cell.
If you want the Common-Lisp style of `flet', you should use `cl-flet'.
The FORMs are evaluated with the specified function definitions in place,
then the definitions are undone (the FUNCs go back to their previous
definitions, or lack thereof).
\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
(declare (indent 1) (debug cl-flet)
;; (obsolete "use either `cl-flet' or `cl-letf'." "24.3")
)
`(letf ,(mapcar
(lambda (x)
(if (or (and (fboundp (car x))
(eq (car-safe (symbol-function (car x))) 'macro))
(cdr (assq (car x) macroexpand-all-environment)))
(error "Use `labels', not `flet', to rebind macro names"))
(let ((func `(cl-function
(lambda ,(cadr x)
(cl-block ,(car x) ,@(cddr x))))))
(when (cl--compiling-file)
;; Bug#411. It would be nice to fix this.
(and (get (car x) 'byte-compile)
(error "Byte-compiling a redefinition of `%s' \
will not work - use `labels' instead" (symbol-name (car x))))
;; FIXME This affects the rest of the file, when it
;; should be restricted to the flet body.
(and (boundp 'byte-compile-function-environment)
(push (cons (car x) (eval func))
byte-compile-function-environment)))
(list `(symbol-function ',(car x)) func)))
bindings)
,@body))
【讨论】: