Some elisp functions that I have installed generate warnings:
`flet\' is an obsolete macro (as of 24.3); use either `cl-flet\' or `cl-letf\'.
The cl-letf
function can be used for dynamic binding of functions, as Artur describes in this blog entry.
I've recently wrote a post on the subject. The gist of the post is that the best replacement for flet
(if you need dynamic binding) is noflet. It's a third party library, but it's almost a drop-in replacement for flet
(while adding some extra capabilities).
You could modify your function to use lawlist-flet
or create an alias -- all I did was remove the warning and rename the flet
macro to 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))
flet
isn't the same as either cl-flet
or cl-letf
.
It's more dangerous (and maybe more powerful). That's why it's being deprecated.
Since it's different (binds dynamically a function name), you have to think
in each case if it's appropriate to replace it with cl-flet
.
flet
can't be replaced with 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
Note that cl-flet
does lexical binding, so the behavior of adder
isn't changed,
while flet
does dynamic binding, which makes add-bunch
temporarily produce a factorial.