Understanding letf and how it replaces flet31 Aug 2014, by Artur Malabarba.
Common-Lisp in Emacs post series
Once you've come to terms with power of
setf, it is time to meet its
cl-letf. As the name implies,
letf is to
let is to
setq, but, once again, that is only the tip of the
To get started, let's have a variable and require the feature.
When temporarily assigning a value to a variable,
letf is (mostly)
They differs slightly in behaviour when you don't provide a value.
let binds the variable to nil and restores it upon exit (as I'm sure
you know), while
letf preserves the current value and restores it
Of course, that's not where
letf shines. It's when you use place
expressions that it simply blows
let out of the water. Let's take a
simple example using our list.
If you're having trouble reading past the three consecutive
parentheses, this snippet simply takes our list and temporarily
changes its first and fourth elements to
“Alright, but how often is that actually useful?”
It all depends on your creativity. This stackoverflow question
highlights a common issue that came up with the release of Emacs 24.3.
flet (short for function-let) was a macro which locally (and
dynamically) replaced the function definition associated to given
symbols. This is extremely useful for error testing, but if you try to
use this macro now you'll get following the message.
Warning: `flet' is an obsolete macro (as of 24.3); use either `cl-flet' or `cl-letf'.
cl-flet is not identical to the original
flet—it's lexical, not dynamic.
For instance, the
url-retrieve-synchronously usually prints a
message on the echo area. Now say you want to prevent that, you can
temporarily rebind the
message function to do nothing.
Now do M-x silent-retrieve, and see that it works.
Unfortunately, if you try to be a good coder and replace the obsolete
flet with the recommended
cl-flet, it won't work!
letf as a replacement for flet
The solution I usually see floating around is to employ Nic Ferrier's fantastic noflet package. But I've never seen anyone mention the built-in option, even though Emacs itself tells you to use it: “use either `cl-flet' or `cl-letf'”.
(symbol-function SYMBOL) is a valid place expression. Which
means you can bind it dynamically using
cl-letf. Evaluate the
following defun and call M-x new-silent-retrieve.
It works! No messaging! All that we've done was tell
temporarily replace the
message function with the
(which does the same thing without echoing). We could also use
ignore instead of
format (the latter just happens to have the same
return value as