* bug#12895: 24.3.50; Replacement for flet
@ 2012-11-15 13:35 Antoine Levitt
2012-11-15 14:46 ` Stefan Monnier
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Antoine Levitt @ 2012-11-15 13:35 UTC (permalink / raw)
To: 12895
Hi,
I'm trying to dynamically bind a function, and used flet
previously. flet is now apparently obsolete. The docstring suggests
using cl-flet. But cl-flet does lexical binding, not dynamic. How do I
get the old behavior (dynamic binding) without using the now-obsolete
flet? I'm confused by the number of subtly different functions to do the
same thing - letf, flet, labels, cl-labels, cl-letf, cl-flet - and find
the docstrings to be unclear. If I understand correctly, letf is what I
need, but the following does not do what I expect it to (ie suppress the
message)
(defun something ()
(message "hi"))
(letf ((message (lambda () (&rest args) nil)))
(something))
Is this because message is a built-in?
Sorry if this has been covered elsewhere, I couldn't find it.
Antoine
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 13:35 bug#12895: 24.3.50; Replacement for flet Antoine Levitt
@ 2012-11-15 14:46 ` Stefan Monnier
2012-11-15 15:01 ` Antoine Levitt
2012-11-16 7:04 ` Katsumi Yamaoka
2012-11-16 1:21 ` Michael Heerdegen
2016-01-31 14:19 ` bug#12895: Status: " Marcin Borkowski
2 siblings, 2 replies; 21+ messages in thread
From: Stefan Monnier @ 2012-11-15 14:46 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895
> (defun something ()
> (message "hi"))
> (letf ((message (lambda () (&rest args) nil)))
> (something))
> Is this because message is a built-in?
No, it's because what you want is not a local function, but an override
of an existing function. Such override should be done with an advice.
Stefan
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 14:46 ` Stefan Monnier
@ 2012-11-15 15:01 ` Antoine Levitt
2012-11-15 18:35 ` Stefan Monnier
2012-11-16 7:04 ` Katsumi Yamaoka
1 sibling, 1 reply; 21+ messages in thread
From: Antoine Levitt @ 2012-11-15 15:01 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 12895
11/15/2012 15:46, Stefan Monnier
>> (defun something ()
>> (message "hi"))
>> (letf ((message (lambda () (&rest args) nil)))
>> (something))
>> Is this because message is a built-in?
>
> No, it's because what you want is not a local function, but an override
> of an existing function.
Ah, sorry. Letf redirects to cl-letf, which says
Temporarily bind to PLACEs. This is the analogue of `let', but with
generalized variables
If it excludes overrides, I think it should say so explicitely. Right
now I'm led to think it's like let for functions, and I've been using
let for overriding just fine.
> Such override should be done with an advice.
Unless I'm missing something easier, using an advice would be cumbersome
(define the advice, activate it, run the function, then deactivate the
advice, protecting for errors). Would you consider un-obsoleting flet?
It isn't deprecated by either cl-flet or cl-letf.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 15:01 ` Antoine Levitt
@ 2012-11-15 18:35 ` Stefan Monnier
2012-11-15 22:42 ` Antoine Levitt
0 siblings, 1 reply; 21+ messages in thread
From: Stefan Monnier @ 2012-11-15 18:35 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895
tags 12895 notabug
thanks
> Temporarily bind to PLACEs. This is the analogue of `let', but with
> generalized variables
> If it excludes overrides, I think it should say so explicitely. Right
> now I'm led to think it's like let for functions, and I've been using
> let for overriding just fine.
letf and cl-letf do not exclude overrides: it only does overrides
(well, pretty much, except if PLACE is a variable, in which case it's
just like a let).
But, indeed, the docstring of cl-flet was wrong since it said "Make
temporary function definitions" whereas these are not temporarily but local.
I just fixed it now, thank you.
>> Such override should be done with an advice.
> Unless I'm missing something easier, using an advice would be cumbersome
> (define the advice, activate it, run the function, then deactivate the
> advice, protecting for errors). Would you consider un-obsoleting flet?
> It isn't deprecated by either cl-flet or cl-letf.
Overriding a function is bad. It can mess things up and throw you
majorly off-course when debugging the problem. So it's good if
it's cumbersome.
Check my recent patch to js.el to see how I replaced flet with advices.
Stefan
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 18:35 ` Stefan Monnier
@ 2012-11-15 22:42 ` Antoine Levitt
2012-11-15 23:05 ` Glenn Morris
2012-11-16 14:34 ` Stefan Monnier
0 siblings, 2 replies; 21+ messages in thread
From: Antoine Levitt @ 2012-11-15 22:42 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 12895
11/15/2012 19:35, Stefan Monnier
>>> Such override should be done with an advice.
>> Unless I'm missing something easier, using an advice would be cumbersome
>> (define the advice, activate it, run the function, then deactivate the
>> advice, protecting for errors). Would you consider un-obsoleting flet?
>> It isn't deprecated by either cl-flet or cl-letf.
>
> Overriding a function is bad. It can mess things up and throw you
> majorly off-course when debugging the problem.
So are advices. I have lots of flet in my .emacs, usually to suppress
messages from functions which are defined elsewhere. For instance,
(defun my-org-agenda-to-appt ()
(interactive)
(flet ((message (&rest args) ))
(org-agenda-to-appt)))
The point is I do not want to redefine org-agenda-to-appt, because I
don't want to have to maintain a parallel copy of it. To get away with
it without too much effort, I'm just going to have to redefine flet
without the obsolete part in my .emacs, which is suboptimal.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 22:42 ` Antoine Levitt
@ 2012-11-15 23:05 ` Glenn Morris
2012-11-15 23:24 ` Antoine Levitt
2012-11-16 14:34 ` Stefan Monnier
1 sibling, 1 reply; 21+ messages in thread
From: Glenn Morris @ 2012-11-15 23:05 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895
Antoine Levitt wrote:
> I have lots of flet in my .emacs, usually to suppress messages from
> functions which are defined elsewhere.
http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12849
may interest you then.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 23:05 ` Glenn Morris
@ 2012-11-15 23:24 ` Antoine Levitt
2012-11-15 23:44 ` Glenn Morris
0 siblings, 1 reply; 21+ messages in thread
From: Antoine Levitt @ 2012-11-15 23:24 UTC (permalink / raw)
To: Glenn Morris; +Cc: 12895
11/16/2012 00:05, Glenn Morris
> Antoine Levitt wrote:
>
>> I have lots of flet in my .emacs, usually to suppress messages from
>> functions which are defined elsewhere.
>
> http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12849
>
> may interest you then.
Ah, nice. But I don't want to prevent messages from going to the
*Messages* buffer, I want to prevent them from appearing in the
minibuffer. For instance, I use this to automatically save the desktop
without being bothered by it
(run-with-timer (* 10 60) (* 10 60)
(lambda ()
(flet ((message (&rest args) nil))
(desktop-save-in-desktop-dir))))
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 23:24 ` Antoine Levitt
@ 2012-11-15 23:44 ` Glenn Morris
2012-11-15 23:47 ` Antoine Levitt
0 siblings, 1 reply; 21+ messages in thread
From: Glenn Morris @ 2012-11-15 23:44 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895
Antoine Levitt wrote:
> But I don't want to prevent messages from going to the *Messages*
> buffer, I want to prevent them from appearing in the minibuffer.
[...]
> (flet ((message (&rest args) nil))
? But this _does_ prevent messages from going to the *Messages* buffer,
as well as to the echo area. And so does binding message-log-max to nil.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 23:44 ` Glenn Morris
@ 2012-11-15 23:47 ` Antoine Levitt
2012-11-15 23:51 ` Glenn Morris
0 siblings, 1 reply; 21+ messages in thread
From: Antoine Levitt @ 2012-11-15 23:47 UTC (permalink / raw)
To: Glenn Morris; +Cc: 12895
11/16/2012 00:44, Glenn Morris
> Antoine Levitt wrote:
>
>> But I don't want to prevent messages from going to the *Messages*
>> buffer, I want to prevent them from appearing in the minibuffer.
> [...]
>> (flet ((message (&rest args) nil))
>
>
> ? But this _does_ prevent messages from going to the *Messages* buffer,
> as well as to the echo area. And so does binding message-log-max to nil.
Sorry if I wasn't clear. I don't care about the *Messages* buffer. What
I do care about is the echo area. Binding message-log-max to nil only
affects logging, not the displaying of the message.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 22:42 ` Antoine Levitt
2012-11-15 23:05 ` Glenn Morris
@ 2012-11-16 14:34 ` Stefan Monnier
2012-11-16 14:49 ` Antoine Levitt
1 sibling, 1 reply; 21+ messages in thread
From: Stefan Monnier @ 2012-11-16 14:34 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895
>> Overriding a function is bad. It can mess things up and throw you
>> majorly off-course when debugging the problem.
> So are advices.
But advices are much more visible (e.g. they appear in C-h f).
> I have lots of flet in my .emacs, usually to suppress
> messages from functions which are defined elsewhere. For instance,
So you need just one advice that adds an `inhibit-message' variable and
then you can let-bind this variable wherever you used flet message.
Stefan
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-16 14:34 ` Stefan Monnier
@ 2012-11-16 14:49 ` Antoine Levitt
2012-11-16 15:24 ` Stefan Monnier
2016-01-31 17:42 ` Michael Heerdegen
0 siblings, 2 replies; 21+ messages in thread
From: Antoine Levitt @ 2012-11-16 14:49 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 12895
11/16/2012 15:34, Stefan Monnier
>>> Overriding a function is bad. It can mess things up and throw you
>>> majorly off-course when debugging the problem.
>> So are advices.
>
> But advices are much more visible (e.g. they appear in C-h f).
>
>> I have lots of flet in my .emacs, usually to suppress
>> messages from functions which are defined elsewhere. For instance,
>
> So you need just one advice that adds an `inhibit-message' variable and
> then you can let-bind this variable wherever you used flet message.
Ah, I didn't see that's what you were doing in js.el. Fair enough, I'll
do that, thanks!
I did like flet, though, and in general, I think it's annoying to users
to remove/deprecate functionality that are neat ways to get inside lisp
code from outside (dynamic-scoping overrides, advices, etc.) just
because they are bad practice and make debugging harder. Some of us are
quite happy not modifying emacs source code but hacking into it from the
comfort of our .emacs. But I do understand your reasons for obsoleting
it.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-16 14:49 ` Antoine Levitt
@ 2012-11-16 15:24 ` Stefan Monnier
2016-01-31 17:42 ` Michael Heerdegen
1 sibling, 0 replies; 21+ messages in thread
From: Stefan Monnier @ 2012-11-16 15:24 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895
> I did like flet, though, and in general, I think it's annoying to
> users to remove/deprecate functionality that are neat ways to get
> inside lisp code from outside (dynamic-scoping overrides, advices,
> etc.) just because they are bad practice and make debugging harder.
The problem with flet is not only that it's doing dangerous things but
also that it's used in code that does not need those dangerous things.
And do not that it was not removed. It was just marked obsolete.
The main purpose of this obsolescence warning is to change the coding
style so that overrides are used explicitly where they're needed and
non-overriding local definitions are used where the override is not
needed, so the code is more clear.
Advising is definitely not on the way out. I even just added a new
lighter weight advice package.
Stefan
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-16 14:49 ` Antoine Levitt
2012-11-16 15:24 ` Stefan Monnier
@ 2016-01-31 17:42 ` Michael Heerdegen
2016-02-09 20:36 ` Antoine Levitt
1 sibling, 1 reply; 21+ messages in thread
From: Michael Heerdegen @ 2016-01-31 17:42 UTC (permalink / raw)
To: Antoine Levitt; +Cc: 12895, Stefan Monnier
Antoine Levitt <antoine.levitt@gmail.com> writes:
> I did like flet, though, and in general, I think it's annoying to users
> to remove/deprecate functionality that are neat ways to get inside lisp
> code from outside (dynamic-scoping overrides, advices, etc.) just
> because they are bad practice and make debugging harder.
BTW, let me add to the (valid) warnings that this can still be achieved
with cl-letf:
(cl-letf (((symbol-function 'some-function) #'some-other-function))
code...)
The created binding to the symbol-function place is dynamical.
Michael.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2016-01-31 17:42 ` Michael Heerdegen
@ 2016-02-09 20:36 ` Antoine Levitt
0 siblings, 0 replies; 21+ messages in thread
From: Antoine Levitt @ 2016-02-09 20:36 UTC (permalink / raw)
To: Michael Heerdegen; +Cc: 12895, Stefan Monnier
[-- Attachment #1: Type: text/plain, Size: 779 bytes --]
That does the trick, thanks for taking the time to respond to such an old
bug report :-)
On 31 January 2016 at 18:42, Michael Heerdegen <michael_heerdegen@web.de>
wrote:
> Antoine Levitt <antoine.levitt@gmail.com> writes:
>
> > I did like flet, though, and in general, I think it's annoying to users
> > to remove/deprecate functionality that are neat ways to get inside lisp
> > code from outside (dynamic-scoping overrides, advices, etc.) just
> > because they are bad practice and make debugging harder.
>
> BTW, let me add to the (valid) warnings that this can still be achieved
> with cl-letf:
>
> (cl-letf (((symbol-function 'some-function) #'some-other-function))
> code...)
>
> The created binding to the symbol-function place is dynamical.
>
>
> Michael.
>
[-- Attachment #2: Type: text/html, Size: 1305 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 14:46 ` Stefan Monnier
2012-11-15 15:01 ` Antoine Levitt
@ 2012-11-16 7:04 ` Katsumi Yamaoka
2012-11-16 14:33 ` Stefan Monnier
1 sibling, 1 reply; 21+ messages in thread
From: Katsumi Yamaoka @ 2012-11-16 7:04 UTC (permalink / raw)
To: monnier; +Cc: 12895, antoine.levitt
Stefan Monnier wrote:
> Such override should be done with an advice.
But why I haven't yet replaced flet used in
message-read-from-minibuffer is that I don't yet have a solution
better than this:
(flet ((mail-abbrev-in-expansion-header-p nil t))
(read-from-minibuffer prompt initial-contents))
;; This makes mail-abbrev-expand work even in a minibuffer, not
;; in a message header.
Not only this, there will probably be lots of situations where
flet is handy to use. Here's the one I've implemented in a
certain package so as to silence the byte compiler:
(defmacro my-flet (bindings &rest body)
"Make temporary overriding function definitions.
\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
`(let (fn origs)
(dolist (bind ',bindings)
(setq fn (car bind))
(push (cons fn (and (fboundp fn) (symbol-function fn))) origs)
(fset fn (cons 'lambda (cdr bind))))
(unwind-protect
(progn ,@body)
(dolist (orig origs)
(if (cdr orig)
(fset (car orig) (cdr orig))
(fmakunbound (car orig)))))))
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-16 7:04 ` Katsumi Yamaoka
@ 2012-11-16 14:33 ` Stefan Monnier
0 siblings, 0 replies; 21+ messages in thread
From: Stefan Monnier @ 2012-11-16 14:33 UTC (permalink / raw)
To: Katsumi Yamaoka; +Cc: 12895, antoine.levitt
> But why I haven't yet replaced flet used in
> message-read-from-minibuffer is that I don't yet have a solution
> better than this:
> (flet ((mail-abbrev-in-expansion-header-p nil t))
> (read-from-minibuffer prompt initial-contents))
How 'bout
(defadvice mail-abbrev-in-expansion-header-p (around t-in-minibuffer activate)
(if (minibufferp) (setq ad-return-value t) ad-do-it))
Or how 'bout filing a feature request?
Stefan
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: 24.3.50; Replacement for flet
2012-11-15 13:35 bug#12895: 24.3.50; Replacement for flet Antoine Levitt
2012-11-15 14:46 ` Stefan Monnier
@ 2012-11-16 1:21 ` Michael Heerdegen
2016-01-31 14:19 ` bug#12895: Status: " Marcin Borkowski
2 siblings, 0 replies; 21+ messages in thread
From: Michael Heerdegen @ 2012-11-16 1:21 UTC (permalink / raw)
To: 12895; +Cc: Antoine Levitt
Hi,
> I'm trying to dynamically bind a function, and used flet
> previously. flet is now apparently obsolete. The docstring suggests
> using cl-flet. But cl-flet does lexical binding, not dynamic. How do I
> get the old behavior (dynamic binding) without using the now-obsolete
> flet? I'm confused by the number of subtly different functions to do the
> same thing - letf, flet, labels, cl-labels, cl-letf, cl-flet - and find
> the docstrings to be unclear. If I understand correctly, letf is what I
> need, but the following does not do what I expect it to (ie suppress the
> message)
No general answer to your question, but something like this my be good
enough for what you want:
(defmacro suppressing-messages (&rest body)
`(let (message-log-max)
(with-temp-message ""
,@body)))
Michael.
^ permalink raw reply [flat|nested] 21+ messages in thread
* bug#12895: Status: 24.3.50; Replacement for flet
2012-11-15 13:35 bug#12895: 24.3.50; Replacement for flet Antoine Levitt
2012-11-15 14:46 ` Stefan Monnier
2012-11-16 1:21 ` Michael Heerdegen
@ 2016-01-31 14:19 ` Marcin Borkowski
2016-01-31 16:51 ` Eli Zaretskii
2 siblings, 1 reply; 21+ messages in thread
From: Marcin Borkowski @ 2016-01-31 14:19 UTC (permalink / raw)
To: bug#12895
Hi all,
just asking: should this "bug report" (which is clearly not a bug report
per se) be closed?
Best,
--
Marcin Borkowski
http://mbork.pl/en
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2016-02-09 20:36 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-15 13:35 bug#12895: 24.3.50; Replacement for flet Antoine Levitt
2012-11-15 14:46 ` Stefan Monnier
2012-11-15 15:01 ` Antoine Levitt
2012-11-15 18:35 ` Stefan Monnier
2012-11-15 22:42 ` Antoine Levitt
2012-11-15 23:05 ` Glenn Morris
2012-11-15 23:24 ` Antoine Levitt
2012-11-15 23:44 ` Glenn Morris
2012-11-15 23:47 ` Antoine Levitt
2012-11-15 23:51 ` Glenn Morris
2012-11-16 14:34 ` Stefan Monnier
2012-11-16 14:49 ` Antoine Levitt
2012-11-16 15:24 ` Stefan Monnier
2016-01-31 17:42 ` Michael Heerdegen
2016-02-09 20:36 ` Antoine Levitt
2012-11-16 7:04 ` Katsumi Yamaoka
2012-11-16 14:33 ` Stefan Monnier
2012-11-16 1:21 ` Michael Heerdegen
2016-01-31 14:19 ` bug#12895: Status: " Marcin Borkowski
2016-01-31 16:51 ` Eli Zaretskii
2016-01-31 17:10 ` Marcin Borkowski
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.