17

我安装的一些 elisp 函数会生成警告:

`flet' is an obsolete macro (as of 24.3); use either `cl-flet' or `cl-letf'.

如果我简单地将所有替换为 会很危险fletcl-flet?如果可以更换它们,哪个更好?

如果更换它不危险,我会向项目发送拉取请求。

他们有什么理由不改变它吗?

4

4 回答 4

10

flet不等于cl-fletor 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临时产生一个阶乘。

于 2013-09-19T13:15:53.347 回答
6

我最近写了一篇关于这个主题的帖子。该帖子的要点是flet(如果您需要动态绑定)的最佳替代品是noflet。它是一个第三方库,但它几乎可以替代flet(同时添加一些额外的功能)。

于 2013-09-19T19:51:09.787 回答
5

cl-letf函数可用于函数的动态绑定,正如 Artur 在博客条目中所描述的那样。

于 2015-03-08T16:00:46.050 回答
1

您可以修改您的函数以使用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))
于 2013-09-19T14:16:35.447 回答