[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: `save-excursion' defeated by `set-buffer'
From: |
Uday Reddy |
Subject: |
Re: `save-excursion' defeated by `set-buffer' |
Date: |
Mon, 14 Mar 2011 01:04:56 +0000 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 |
On 3/13/2011 6:22 PM, Drew Adams wrote:
So? As I said, the warning was discussed, and getting rid of it was rejected.
You are convinced that that's a great decision; I am not. No way of knowing
what most people felt or feel, and it doesn't matter because polls are not taken
anymore when deciding... (Poor Emacs.)
No, polls are not in. It was pointed out that the Gnu project is not a
democracy. It is an enlightened dictatorship in the Socratic style. I
am a great fan of Socrates myself and I wouldn't want the Gnu project to
go down the tube like the Athenian democracy did.
This particular warning is in the 'suspicious category.
It signals that the code is suspicious.
Only if you think that using `save-excursion' with `set-buffer' is suspicious,
which in general it is not.
David K's example in the message you cite below is one that involves
user interaction. So, you can't wrap save-excursion around it. One can
hardly generalize from such a special case.
Wrt the supposed danger, David K replied this to Stefan (who replied to me,
defining the danger)
http://lists.gnu.org/archive/html/emacs-devel/2010-01/msg00588.html:
>
just what is inherently wrong or dangerous (meriting a
warning) with code like the following, to do some work in other buffers yet
return to the original buffer AND restore its point and mark?
(save-excursion
(set-buffer FOO)
; Pick up some info in FOO,& perhaps assign it to a var
(set-buffer BAR)
; Calculate something in BAR,& perhaps record it too
...
)
What is dangerous about it is that dependong on which buffer is current
before executing this code, the point-saving will either do something
or nothing.
Wrong. It will always restore the _original_ buffer and its point on
exit of the save-excursion form.
I don't see anything "wrong" in Stefan's point. Whether the code has a
side effect or not depends on which buffer it is running in. It has a
side effect on any buffer except the current buffer. That is strange
and buggy code. Stefan's point stands.
I am not sure what David's point is. actually. "It will always restore
the original buffer and its point." But, what is so special about the
original buffer? Is it fine for the code to muck up every buffer other
than the original buffer?
David is correct of course. And Stefan's explanation of the "danger" does not
indicate any danger, in any case. Where's the beef?
I haven't seen Stefan use words like "danger". He said that it led to
buggy code. Here is a direct quote:
"The precise behavior of (save-excusrion (set-buffer foo) ...) is
sufficiently odd that I still haven't come upon a single real case where
it was the right thing to do. Yet, this precise form is (well, was)
found more than a hundred times in the Emacs source code."
I for one would be very wary of using anybody's code that generates
such warnings.
That is precisely one of the problems created by this misguided message. Users
get freaked out seeing WARNINGs when they byte-compile the code. They don't
understand the message (even seasoned developers differ in their guesses as to
its meaning), and the unknown scares them.
I agree that the users/developers need to be given more help. That is
why I have been working on edits to the manual.
I probably overstated my wariness in my previous message. Code that
generates the "suspicious" warnings is not necessarily dysfunctional.
It is just fragile. It can break when modified or extended. But what I
would be really wary of developers that fail to understand the issue and
blame it all on the compiler stupidity instead.
More seriously, RMS et al who created `save-excursion' were not idiots. They
explicitly designed it to save and restore which buffer is current, in addition
to its point and mark. Why, do you suppose?
They designed them in the early days and those were good first-cut
solutions. But we learn from experience and make progress. Now,
`save-current-buffer' represents one half of `save-excursion', and it is
exactly the half that is relevant to `set-buffer'. So, when the elisp
gurus recommend that you use that instead of `save-excursion', why is
there this resistance? Why these endless debates?
And most users of it over the years have used it well - without any warnings.
If you automatically think that such a warning indicates bad code or inadequate
knowledge of Emacs Lisp then you are jumping to a wild, indiscriminate
conclusion, IMO.
They haven't used it well. It is really not possible to use it
correctly. Slapping a save-excursion at the top level hides all the
side effects and you don't know what unwanted side effects have occurred
inside the code. As you know, I maintain VM which was developed by a
star programmer like Kyle Jones. But if I replace its save-excursion's
by save-current-buffer's, it falls down pretty badly, with the buffer
points moving in all kinds of unpredictable ways. For all I know, there
might be only one or two unprotected point movements in there. But they
are enough to wreak havoc. Tracking them down is incredibly hard. The
best I can do is to replace a few save-excursions at a time and watch
carefully to see if anything goes wrong. It will take me a long time to
get rid of all the save-excursions.
So, my best advice would be, don't do it. Don't use save-excursion with
set-buffer. It is completely illogical. There is no need for it. The
compiler is right. Please pay attention.
Cheers,
Uday
- Re: `save-excursion' defeated by `set-buffer', (continued)
- Message not available
- Re: `save-excursion' defeated by `set-buffer', Stefan Monnier, 2011/03/11
- Re: `save-excursion' defeated by `set-buffer', Eli Zaretskii, 2011/03/12
- Re: `save-excursion' defeated by `set-buffer', Andreas Röhler, 2011/03/12
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/12
- Re: `save-excursion' defeated by `set-buffer', Eli Zaretskii, 2011/03/12
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/12
- Re: `save-excursion' defeated by `set-buffer', Juanma Barranquero, 2011/03/14
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/14
- Message not available
- Re: `save-excursion' defeated by `set-buffer', Uday Reddy, 2011/03/12
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/13
- Message not available
- Re: `save-excursion' defeated by `set-buffer',
Uday Reddy <=
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/14
- Message not available
- Re: `save-excursion' defeated by `set-buffer', Tim X, 2011/03/12
- Re: `save-excursion' defeated by `set-buffer', Andreas Röhler, 2011/03/13
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/13
- Message not available
- Re: `save-excursion' defeated by `set-buffer', Uday Reddy, 2011/03/13
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/13
- Message not available
- Re: `save-excursion' defeated by `set-buffer', Uday Reddy, 2011/03/13
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/13
- Re: `save-excursion' defeated by `set-buffer', Uday S Reddy, 2011/03/13
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/14