all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Drew Adams" <drew.adams@oracle.com>
To: "'Andreas Röhler'" <andreas.roehler@easy-emacs.de>,
	help-gnu-emacs@gnu.org
Subject: RE: `save-excursion' defeated by `set-buffer'
Date: Sun, 13 Mar 2011 11:23:40 -0700	[thread overview]
Message-ID: <89343AC9BC9947EDABCE396F1CE1220F@us.oracle.com> (raw)
In-Reply-To: <4D7C6F2C.5050008@easy-emacs.de>

> > I think it is a little more subtle than that. People may be using it
> > under the expectation that point and mark will also be saved in the
> > buffer accessed by set-buffer.
> 
> wherefrom you assume that?  AFAIU buffer, point and mark are
> stored the very moment `(save-excursion' cames in.
> 
> They should be restored if the parentese closes.
> Every setting of buffer, mark and point between then doesn't 
> matter as far as the buffer now current again is concerned.
> 
> Maybe there have been other `save-excursion' intercurse. But 
> every one tells it's own story.

Exactly.  Andreas is exactly right.  The emperor has no clothes.

> What's the difficulty?

You're right, Andreas - there isn't any.  The doc string of `save-excursion'
says it all, and quite clearly too.

The only possible confusion it lets in, IMO, is via the wording "save...current
buffer" in the first line.  But it then more carefully makes clear that the
buffer _content_ is not _saved_ as in saving to a file; instead, what is "saved"
(remembered) is which buffer is current, and that buffer is made current again
at the end.  And that possible confusion exists just as much - no, more, for the
innocent, praised, and now unduly privileged `save-current-buffer'.

But the issue of that possible confusion has not even been raised by those who
want to warn us about using `save-excursion' with `set-buffer'.  The purported
"problems" they cite have nothing to do with the ambiguous wording about
"saving" the current buffer.

They have to do with users supposedly assuming that `set-buffer' itself saves or
restores state (which buffer is current, or point, or mark) - put differently,
that a `set-buffer' somehow overrides a surrounding `save-excursion', preventing
it from restoring things.  These "problems" have nothing to do with
`save-excursion' or its doc.  If there is any teaching to be done about such
"problems" then it should be done in the doc of `set-buffer'.

On the other hand, Stefan has also claimed that users think that
`save-excursion' will also restore point in other buffers, in particular, in the
`set-buffer' buffers.  Again, the `save-excursion' doc is very clear about this.
If users are confused in this way (no evidence was given) then teach them with
doc, not with blanket warnings that say nothing.

Supposedly people are making these false assumptions all over the place and the
result is buggy code.  Users purportedly think that `save-excursion' does not
restore the point or the mark if there is a `set-buffer' in the body, that the
`set-buffer' takes precedence and any movements after it leave the point or mark
changed beyond the end of the excursion.  Or they purportedly think that
`save-excursion' restores point and mark in more than one buffer.  IOW, users
can't be trusted to read well and code well; they need to be warned.

The variants of the first purported misconception (`set-buffer' overrides
`save-excursion') have to do with whether the target of `set-buffer' is the same
buffer as was saved by `save-excursion'.  Supposedly `save-current-buffer' is
"safer" because it (correctly) leads no one to suppose that point and mark will
be restored.

The mildest variant of this problem is when the user doesn't really want or need
to save and restore point and mark - s?he just wants to restore which buffer is
current.  Stefan says that using `save-excursion' instead of
`save-current-buffer' or `with-current-buffer' is then "inefficient".  Well,
sure, a little bit...  It's (inexpensive) overkill.  But a _warning_?

I have not seen that people are willy-nilly falsely assuming that a `set-buffer'
inside a `save-excursion' overrides it.

I'm sure that a few such bugs have been introduced somewhere, but this kind of
thing can happen also with (let ((a b))...(setq a c)...).  We do not _warn_
people that "`let' defeats `setq'" just because `let' restores a value set by
`setq'.  (Yes, I know the analogy is imperfect; I know there are different `a's
etc.)  We expect users to read the `let' doc and learn to use it correctly.

I also have not seen that people falsely assume that `save-excursion' restores
point for more than the buffer that was current when it was invoked.  Maybe
someone has misunderstood this way, but issue a _warning_ each time
`save-excursion' is used with `set-buffer'?

`save-excursion' simply remembers where you are and returns there when the
excursion is finished.  End of story.  The "where you are" includes the buffer,
your position in that buffer (point), the mark (if any) in that buffer, and
whether the mark was active.

If a non-local exit (e.g. `top-level' or `throw' outside the `save-excursion')
occurs while evaluating the `save-excursion' body then the rest of that body is
not evaluated (naturally).  But the saved information is still restored (which
buffer is current, plus its value of point and mark).  That completes the
behavior of `save-excursion'.  And all of the behavior is explained in the doc
string.

If someone is convinced that `save-excursion' is evil or is too hard for
Emacs-Lisp users to figure out, and s?he wants to teach better programming
practices, the way to do that is not to set off the fire alarm each time code
uses `set-buffer' inside `set-excursion'.




  reply	other threads:[~2011-03-13 18:23 UTC|newest]

Thread overview: 113+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <mailman.0.1299085819.4487.help-gnu-emacs@gnu.org>
2011-03-02 20:54 ` `save-excursion' defeated by `set-buffer' Uday Reddy
2011-03-05  4:28 ` Stefan Monnier
2011-03-10 19:57   ` Andreas Röhler
2011-03-11  1:07     ` Leo
2011-03-11  1:28     ` Stefan Monnier
2011-03-11  8:52       ` Andreas Röhler
     [not found]       ` <mailman.25.1299833256.26376.help-gnu-emacs@gnu.org>
2011-03-11  9:54         ` David Kastrup
2011-03-11 11:09           ` Andreas Röhler
     [not found]           ` <mailman.10.1299841456.13496.help-gnu-emacs@gnu.org>
2011-03-11 11:38             ` David Kastrup
2011-03-11 15:52         ` Stefan Monnier
2011-03-12  8:59           ` Eli Zaretskii
2011-03-12 19:00             ` Andreas Röhler
2011-03-12 19:56               ` Drew Adams
2011-03-12 20:27                 ` Eli Zaretskii
2011-03-12 22:20                   ` Drew Adams
2011-03-14 18:59                 ` Juanma Barranquero
2011-03-14 21:17                   ` Drew Adams
     [not found]               ` <mailman.6.1299959800.9013.help-gnu-emacs@gnu.org>
2011-03-13  3:00                 ` Uday Reddy
2011-03-13 18:22                   ` Drew Adams
     [not found]                   ` <mailman.0.1300040583.10860.help-gnu-emacs@gnu.org>
2011-03-14  1:04                     ` Uday Reddy
2011-03-14  8:43                       ` Drew Adams
     [not found]             ` <mailman.4.1299956141.9013.help-gnu-emacs@gnu.org>
2011-03-12 22:29               ` Tim X
2011-03-13  7:15                 ` Andreas Röhler
2011-03-13 18:23                   ` Drew Adams [this message]
2011-03-13 12:46                 ` Uday S Reddy
2011-03-14  8:47                   ` Drew Adams
     [not found]                   ` <mailman.7.1300092490.2602.help-gnu-emacs@gnu.org>
2011-03-14 12:22                     ` Uday Reddy
2011-03-14 14:20                     ` Uday S Reddy
2011-03-14 17:36                       ` Drew Adams
2011-03-14 23:20                         ` Uday S Reddy
2011-03-15  3:55                           ` Drew Adams
     [not found]                       ` <mailman.14.1300124226.2531.help-gnu-emacs@gnu.org>
2011-03-15 14:39                         ` Stefan Monnier
2011-03-15 15:59                           ` Drew Adams
     [not found]                           ` <mailman.2.1300204800.1264.help-gnu-emacs@gnu.org>
2011-03-15 17:46                             ` Stefan Monnier
2011-03-15 18:55                               ` Drew Adams
2011-03-14 14:18                   ` Andreas Röhler
     [not found]                   ` <mailman.5.1300111985.27831.help-gnu-emacs@gnu.org>
2011-03-14 14:54                     ` Uday Reddy
     [not found]                 ` <mailman.5.1300000253.31664.help-gnu-emacs@gnu.org>
2011-03-13 14:16                   ` Uday Reddy
2011-03-13 18:25                     ` Drew Adams
     [not found]                     ` <mailman.2.1300040743.10860.help-gnu-emacs@gnu.org>
2011-03-13 20:48                       ` Uday Reddy
2011-03-14  0:31                         ` Drew Adams
     [not found]                 ` <mailman.4.1300066631.25374.help-gnu-emacs@gnu.org>
2011-03-14 14:34                   ` Stefan Monnier
2011-03-13  2:11               ` Uday Reddy
2011-03-13 18:26                 ` Drew Adams
     [not found]           ` <mailman.5.1299920357.7270.help-gnu-emacs@gnu.org>
2011-03-12  9:34             ` David Kastrup
2011-03-12 10:12               ` Eli Zaretskii
     [not found]               ` <mailman.10.1299924724.7270.help-gnu-emacs@gnu.org>
2011-03-12 10:42                 ` David Kastrup
2011-03-12 12:28                   ` Eli Zaretskii
2011-03-12 15:17                   ` Uday Reddy
2011-03-12 15:25                     ` David Kastrup
2011-03-13  2:40                       ` Uday Reddy
2011-03-14 14:25                         ` Stefan Monnier
2011-03-14 17:26                           ` Andreas Röhler
     [not found]                           ` <mailman.11.1300123292.2531.help-gnu-emacs@gnu.org>
2011-03-15 14:35                             ` Stefan Monnier
2011-03-15 14:47                               ` David Kastrup
2011-03-15 15:19                               ` PJ Weisberg
2011-03-15 16:00                               ` Drew Adams
     [not found]                               ` <mailman.6.1300202904.14512.help-gnu-emacs@gnu.org>
2011-03-15 17:42                                 ` Stefan Monnier
     [not found]                               ` <mailman.3.1300204850.1264.help-gnu-emacs@gnu.org>
2011-03-15 17:49                                 ` Stefan Monnier
2011-03-15 18:56                                   ` Drew Adams
2011-03-15 21:30                                     ` Stefan Monnier
2011-03-15 19:02                                   ` Jason Earl
2011-03-15 20:55                                     ` Drew Adams
2011-03-16  4:31                                     ` rusi
2011-03-16  8:11                                       ` David Kastrup
2011-03-17  3:46                                         ` rusi
2011-03-17  7:10                                           ` rusi
2011-03-17  8:29                                             ` Antoine Levitt
     [not found]                                   ` <mailman.1.1300215374.6982.help-gnu-emacs@gnu.org>
2011-03-16 12:05                                     ` Uday S Reddy
2011-03-12 22:18             ` Tim X
2011-03-11 23:06         ` Uday Reddy
2011-03-10 22:40   ` David Kastrup
2011-03-11  2:46     ` Stefan Monnier
2011-04-01  3:20 ` rusi
2011-04-01 12:39   ` Uday Reddy
2011-03-02 17:12 Andreas Röhler
2011-03-03  4:58 ` Le Wang
     [not found] ` <mailman.7.1299128292.20537.help-gnu-emacs@gnu.org>
2011-03-13 15:05   ` Uday Reddy
  -- strict thread matches above, loose matches on Subject: below --
2009-12-20 19:19 Roland Winkler
2009-12-21 15:26 ` Stefan Monnier
2009-12-21 16:23   ` David Kastrup
2009-12-22 12:51     ` martin rudalics
2009-12-23  0:45     ` Stefan Monnier
2009-12-23  9:07       ` David Kastrup
2009-12-24  4:35         ` Stefan Monnier
2009-12-24  9:03           ` David Kastrup
2009-12-29 16:01             ` Stefan Monnier
2010-01-04  9:09               ` Drew Adams
2010-01-04 18:30                 ` Stefan Monnier
2010-01-05 20:17                   ` David Kastrup
2010-01-06  0:02                     ` Drew Adams
2010-01-06  4:20                       ` Stefan Monnier
2010-01-06  8:07                         ` David Kastrup
2010-01-06  8:57                           ` Drew Adams
2010-01-10  4:57                             ` Stefan Monnier
2010-01-10  8:12                               ` David Kastrup
2010-01-10 21:43                                 ` Stefan Monnier
2010-01-11  8:24                                   ` David Kastrup
2010-01-11  9:21                                     ` martin rudalics
2010-01-11 16:50                                       ` Stefan Monnier
2010-01-10 17:03                               ` Drew Adams
2010-01-10  4:51                           ` Stefan Monnier
2010-01-10 15:58                         ` Harald Hanche-Olsen
2010-01-10 18:05                           ` martin rudalics
2010-01-10 18:06                           ` Drew Adams
2010-01-10 19:44                             ` Harald Hanche-Olsen
2009-12-24 14:04   ` Roland Winkler
2010-01-04 17:08   ` Davis Herring
2010-01-04 17:34     ` David Kastrup
2010-01-04 18:33     ` Stefan Monnier
2009-12-18  9:20 Eli Zaretskii
2009-12-18 15:29 ` Juanma Barranquero
2009-12-18 15:58   ` Thierry Volpiatto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=89343AC9BC9947EDABCE396F1CE1220F@us.oracle.com \
    --to=drew.adams@oracle.com \
    --cc=andreas.roehler@easy-emacs.de \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.