help-gnu-emacs
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]