unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Change in files.el
@ 2017-01-28  2:16 Richard Stallman
  2017-01-28  2:46 ` Stefan Monnier
  2017-02-04  9:18 ` Eli Zaretskii
  0 siblings, 2 replies; 33+ messages in thread
From: Richard Stallman @ 2017-01-28  2:16 UTC (permalink / raw)
  To: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

Would someone please install this for me so that I don't have to
struggle with git?


log entry

Allow a default predicate for save-some-buffers.
* files.el (save-some-buffers-default-predicate): New defcustom.
(save-some-buffers): Use that predicate when nil specified.

NEWS:

** `save-some-buffers' now uses `save-some-buffers-default-predicate'
to decide which buffers to ask about, PRED is nil.

diff -u /home/rms/emacs-git/build-dec-29/lisp/files.el.\~1\~ /home/rms/emacs-git/build-dec-29/lisp/files.el
--- /home/rms/emacs-git/build-dec-29/lisp/files.el.~1~	2016-12-29 05:00:58.335998032 -0500
+++ /home/rms/emacs-git/build-dec-29/lisp/files.el	2017-01-27 09:29:16.747005021 -0500
@@ -5132,6 +5132,13 @@
   "Non-nil means `save-some-buffers' should save this buffer without asking.")
 (make-variable-buffer-local 'buffer-save-without-query)
 
+(defcustom save-some-buffers-default-predicate nil
+  "Default predicate for `save-some-buffers'.
+This allows you to stop `save-some-buffers' from asking
+about certain files that you'd usually rather not save."
+  :group 'auto-save
+  :type 'function)
+
 (defun save-some-buffers (&optional arg pred)
   "Save some modified file-visiting buffers.  Asks user about each one.
 You can answer `y' to save, `n' not to save, `C-r' to look at the
@@ -5147,10 +5154,13 @@
 If PRED is t, then certain non-file buffers will also be considered.
 If PRED is a zero-argument function, it indicates for each buffer whether
 to consider it or not when called with that buffer current.
+PRED defaults to the value of `save-some-buffers-default-predicate'.
 
 See `save-some-buffers-action-alist' if you want to
 change the additional actions you can take on files."
   (interactive "P")
+  (unless pred
+    (setq pred save-some-buffers-default-predicate))
   (save-window-excursion
     (let* (queried autosaved-buffers
 	   files-done abbrevs-done)
@@ -6810,6 +6820,8 @@
 Runs the members of `kill-emacs-query-functions' in turn and stops
 if any returns nil.  If `confirm-kill-emacs' is non-nil, calls it."
   (interactive "P")
+  ;; Don't use save-some-buffers-default-predicate, because we want
+  ;; to ask about all the buffers before killing Emacs.
   (save-some-buffers arg t)
   (let ((confirm confirm-kill-emacs))
     (and

Diff finished.  Fri Jan 27 09:29:25 2017

-- 
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28  2:16 Change in files.el Richard Stallman
@ 2017-01-28  2:46 ` Stefan Monnier
  2017-01-28  9:10   ` Eli Zaretskii
  2017-02-04  9:18 ` Eli Zaretskii
  1 sibling, 1 reply; 33+ messages in thread
From: Stefan Monnier @ 2017-01-28  2:46 UTC (permalink / raw)
  To: emacs-devel

> +(defcustom save-some-buffers-default-predicate nil
> +  "Default predicate for `save-some-buffers'.
> +This allows you to stop `save-some-buffers' from asking
> +about certain files that you'd usually rather not save."

Please make it so that the var *always* has a function value.
I.e. the default should not be nil but should be the actual
default predicate.


        Stefan




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28  2:46 ` Stefan Monnier
@ 2017-01-28  9:10   ` Eli Zaretskii
  2017-01-28 14:40     ` Stefan Monnier
  0 siblings, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28  9:10 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Fri, 27 Jan 2017 21:46:06 -0500
> 
> > +(defcustom save-some-buffers-default-predicate nil
> > +  "Default predicate for `save-some-buffers'.
> > +This allows you to stop `save-some-buffers' from asking
> > +about certain files that you'd usually rather not save."
> 
> Please make it so that the var *always* has a function value.

Why is that important?



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28  9:10   ` Eli Zaretskii
@ 2017-01-28 14:40     ` Stefan Monnier
  2017-01-28 14:57       ` Eli Zaretskii
  2017-01-29  0:21       ` Richard Stallman
  0 siblings, 2 replies; 33+ messages in thread
From: Stefan Monnier @ 2017-01-28 14:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

>> > +(defcustom save-some-buffers-default-predicate nil
>> > +  "Default predicate for `save-some-buffers'.
>> > +This allows you to stop `save-some-buffers' from asking
>> > +about certain files that you'd usually rather not save."
>> Please make it so that the var *always* has a function value.
> Why is that important?

- So that you don't have to wrap each and every use inside an `if'.
- Or so you don't have to fix the docstring to say what happens when the
  value is nil.
- Or so you can use `add-function' on it.
- More generally, so that you can slightly change its behavior without
  having to re-implement the default behavior by hand.
- Also, so as to make sure that it is *possible* to reimplement the
  default behavior by hand (i.e. to make sure the predicate has access to all
  the info it needs to reproduce the default behavior).

This is a rule we should try to follow for all *-function and
*-predicate variables (as well as similar cases, such as
process-filters and sentinels).


        Stefan



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 14:40     ` Stefan Monnier
@ 2017-01-28 14:57       ` Eli Zaretskii
  2017-01-28 15:31         ` Dmitry Gutov
  2017-01-28 15:40         ` Stefan Monnier
  2017-01-29  0:21       ` Richard Stallman
  1 sibling, 2 replies; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 14:57 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: emacs-devel@gnu.org
> Date: Sat, 28 Jan 2017 09:40:11 -0500
> 
> >> Please make it so that the var *always* has a function value.
> > Why is that important?
> 
> - So that you don't have to wrap each and every use inside an `if'.
> - Or so you don't have to fix the docstring to say what happens when the
>   value is nil.
> - Or so you can use `add-function' on it.
> - More generally, so that you can slightly change its behavior without
>   having to re-implement the default behavior by hand.
> - Also, so as to make sure that it is *possible* to reimplement the
>   default behavior by hand (i.e. to make sure the predicate has access to all
>   the info it needs to reproduce the default behavior).

These sound minor to me (and the last two are also possible without
the requirement, AFAIU).  By contrast, insisting on a function value
instead of the default nil forces me to go through at least one more
level of indirection when I need to understand what happens in a
function that references such variables, which sounds like a more
serious trouble from my POV.  I was up to my neck in this when I
needed to document all the various optional behaviors implemented in
isearch.el, and bumped into similar issues several times elsewhere.

So IME following that rule is a net loss.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 14:57       ` Eli Zaretskii
@ 2017-01-28 15:31         ` Dmitry Gutov
  2017-01-28 16:12           ` Eli Zaretskii
  2017-01-28 15:40         ` Stefan Monnier
  1 sibling, 1 reply; 33+ messages in thread
From: Dmitry Gutov @ 2017-01-28 15:31 UTC (permalink / raw)
  To: Eli Zaretskii, Stefan Monnier; +Cc: emacs-devel

On 28.01.2017 17:57, Eli Zaretskii wrote:

> These sound minor to me (and the last two are also possible without
> the requirement, AFAIU).  By contrast, insisting on a function value
> instead of the default nil forces me to go through at least one more
> level of indirection when I need to understand what happens in a
> function that references such variables, which sounds like a more
> serious trouble from my POV.

It's just one more level of indirection. We routinely deal with dozens 
of them. This above rule should just be adhered consistently, and the 
indirection won't be a surprise every time.

On the plus side, you might get a smaller function that calls the 
-default one, because some code will be extracted.

Finally, the default value of save-some-buffers-default-predicate can be 
#'ignore or #'identity (it's either this, or the previous paragraph, I'm 
not familiar with the code enough to be sure).

> I was up to my neck in this when I
> needed to document all the various optional behaviors implemented in
> isearch.el, and bumped into similar issues several times elsewhere.

isearch.el and etags.el have more egregious problems, such as extensive 
use of dynamic bindings.




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 14:57       ` Eli Zaretskii
  2017-01-28 15:31         ` Dmitry Gutov
@ 2017-01-28 15:40         ` Stefan Monnier
  2017-01-28 16:08           ` Eli Zaretskii
  1 sibling, 1 reply; 33+ messages in thread
From: Stefan Monnier @ 2017-01-28 15:40 UTC (permalink / raw)
  To: emacs-devel

>> - So that you don't have to wrap each and every use inside an `if'.
>> - Or so you don't have to fix the docstring to say what happens when the
>> value is nil.
>> - Or so you can use `add-function' on it.
>> - More generally, so that you can slightly change its behavior without
>> having to re-implement the default behavior by hand.
>> - Also, so as to make sure that it is *possible* to reimplement the
>> default behavior by hand (i.e. to make sure the predicate has access to all
>> the info it needs to reproduce the default behavior).
> These sound minor to me (and the last two are also possible without
> the requirement, AFAIU).

Hmm... how do you get the last two without that requirement?

> By contrast, insisting on a function value instead of the default nil
> forces me to go through at least one more level of indirection when
> I need to understand what happens in a function that references such
> variables, which sounds like a more serious trouble from my POV.

I don't follow, sorry.  I don't understand what you mean by "go through
at least one more level of indirection" here.  Could you explain with
an example.


        Stefan




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 15:40         ` Stefan Monnier
@ 2017-01-28 16:08           ` Eli Zaretskii
  2017-01-28 16:51             ` Stefan Monnier
  0 siblings, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 16:08 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Sat, 28 Jan 2017 10:40:41 -0500
> 
> >> - So that you don't have to wrap each and every use inside an `if'.
> >> - Or so you don't have to fix the docstring to say what happens when the
> >> value is nil.
> >> - Or so you can use `add-function' on it.
> >> - More generally, so that you can slightly change its behavior without
> >> having to re-implement the default behavior by hand.
> >> - Also, so as to make sure that it is *possible* to reimplement the
> >> default behavior by hand (i.e. to make sure the predicate has access to all
> >> the info it needs to reproduce the default behavior).
> > These sound minor to me (and the last two are also possible without
> > the requirement, AFAIU).
> 
> Hmm... how do you get the last two without that requirement?

Are we still talking about a predicate, i.e. a function that returns
either t or nil?  If so, I think the last two are so trivial that I
don't know where to begin answering your question.

> > By contrast, insisting on a function value instead of the default nil
> > forces me to go through at least one more level of indirection when
> > I need to understand what happens in a function that references such
> > variables, which sounds like a more serious trouble from my POV.
> 
> I don't follow, sorry.  I don't understand what you mean by "go through
> at least one more level of indirection" here.  Could you explain with
> an example.

Let's say I'm looking at this code:

  (defcustom save-some-buffers-default-predicate nil
  ...)

  (unless pred
    (setq pred save-some-buffers-default-predicate))
  (if pred DO-SOMETHING)

Here I know immediately what happens when PRED is nil and
save-some-buffers-default-predicate is at its default value.  By
contrast, this:

  (defcustom save-some-buffers-default-predicate #'some-func
  ...)

  (if save-some-buffers-default-predicate DO-SOMETHING)

requires me to go and look at some-func, which is "one more level of
indirection".



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 15:31         ` Dmitry Gutov
@ 2017-01-28 16:12           ` Eli Zaretskii
  0 siblings, 0 replies; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 16:12 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: monnier, emacs-devel

> Cc: emacs-devel@gnu.org
> From: Dmitry Gutov <dgutov@yandex.ru>
> Date: Sat, 28 Jan 2017 18:31:29 +0300
> 
> On 28.01.2017 17:57, Eli Zaretskii wrote:
> 
> > These sound minor to me (and the last two are also possible without
> > the requirement, AFAIU).  By contrast, insisting on a function value
> > instead of the default nil forces me to go through at least one more
> > level of indirection when I need to understand what happens in a
> > function that references such variables, which sounds like a more
> > serious trouble from my POV.
> 
> It's just one more level of indirection. We routinely deal with dozens 
> of them.

Each one is an additional annoyance, making maintenance harder.  Given
enough levels of indirection, it is practically impossible to
understand what the code does just by looking at the source; you need
to actually step through it in a debugger.  And that makes maintenance
a PITA, and in some cases might cause me to give up on a problem in
despair.

> This above rule should just be adhered consistently, and the
> indirection won't be a surprise every time.

There's no surprise here, only the annoying need to wade through
indirection levels.

> On the plus side, you might get a smaller function that calls the 
> -default one, because some code will be extracted.

That's only a plus when you need to write that code, not when you need
to understand or debug it.

> Finally, the default value of save-some-buffers-default-predicate can be 
> #'ignore or #'identity (it's either this, or the previous paragraph, I'm 
> not familiar with the code enough to be sure).

For predicates that need to return nil or t, the default value might
be ridiculous, if it has to be wrapped in a function.

> > I was up to my neck in this when I
> > needed to document all the various optional behaviors implemented in
> > isearch.el, and bumped into similar issues several times elsewhere.
> 
> isearch.el and etags.el have more egregious problems, such as extensive 
> use of dynamic bindings.

Yes, and using indirection doesn't help there.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 16:08           ` Eli Zaretskii
@ 2017-01-28 16:51             ` Stefan Monnier
  2017-01-28 17:11               ` Eli Zaretskii
  0 siblings, 1 reply; 33+ messages in thread
From: Stefan Monnier @ 2017-01-28 16:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

>> >> - More generally, so that you can slightly change its behavior without
>> >> having to re-implement the default behavior by hand.
>> >> - Also, so as to make sure that it is *possible* to reimplement
>> >> the default behavior by hand (i.e. to make sure the predicate has
>> >> access to all the info it needs to reproduce the default
>> >> behavior).
>> > These sound minor to me (and the last two are also possible without
>> > the requirement, AFAIU).
>> Hmm... how do you get the last two without that requirement?
> Are we still talking about a predicate, i.e. a function that returns
> either t or nil?  If so, I think the last two are so trivial that I
> don't know where to begin answering your question.

I don't see what the form of the return value changes to the problem.

Regarding "More generally, so that you can slightly change its
behavior without having to re-implement the default behavior by hand":
- what code would you write which preserves the behavior except that it
  logs all calls to some global variable?
- what code would you write which preserves the behavior except that it
  returns nil for one specific buffer?

Regarding "Also, so as to make sure that it is *possible* to reimplement
the default behavior by hand": in my experience trying to change
*-function to default to a non-nil value, it often happens that the
preexisting default behavior *cannot* be implemented faithfully (or
without a lot of extra gymnastic) because it relies on some local
variable which is not passed as argument to the predicate.
The situation is often worse when the code is written in C, where the
fix sometimes involves exporting new vars to Elisp, an that sometimes
proves problematic because that var was not designed to be accessible to
random code.

>   (defcustom save-some-buffers-default-predicate #'some-func
>   ...)
>
>   (if save-some-buffers-default-predicate DO-SOMETHING)

[ Side note: "(if save-some-buffers-default-predicate ...)" is already
  a bad idea.  the only thing you should do with such a var is pass it to
  `funcall` or `apply`.  ]

> requires me to go and look at some-func, which is "one more level of
> indirection".

I see what you mean.  Yes, the default behavior ends up moved into its
own function.  I'm surprised you feel so strongly about it, tho, because
it never caused me such trouble.

When debugging a specific execution, I'm usually doing it with Edebug,
and indeed it might require some extra instrumentation step to get
Edebug to enter `some-func`, but that hasn't been terribly annoying
(otherwise, I'd have gotten around around to making `i` work on funcall
to automate the extra step).  And when just reading the code without any
specific execution in mind, I typically don't look at the value of
save-some-buffers-default-predicate at all since the code should work
correctly regardless of that value and the same problem shows up if the
(funcall save-some-buffers-default-predicate) is replaced by

    (if save-some-buffers-default-predicate
        (funcall save-some-buffers-default-predicate ..args..))
      ..do-the-default-thing..)


-- Stefan



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 16:51             ` Stefan Monnier
@ 2017-01-28 17:11               ` Eli Zaretskii
  2017-01-28 17:22                 ` Stefan Monnier
  0 siblings, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 17:11 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: emacs-devel@gnu.org
> Date: Sat, 28 Jan 2017 11:51:07 -0500
> 
> >> > These sound minor to me (and the last two are also possible without
> >> > the requirement, AFAIU).
> >> Hmm... how do you get the last two without that requirement?
> > Are we still talking about a predicate, i.e. a function that returns
> > either t or nil?  If so, I think the last two are so trivial that I
> > don't know where to begin answering your question.
> 
> I don't see what the form of the return value changes to the problem.

The default behavior is just the value t or nil, so reproducing the
default behavior is trivial.  E.g., in the case in point the default
behavior is to always ask the user about every buffer, i.e. the
default implementation simply always returns t.

> Regarding "More generally, so that you can slightly change its
> behavior without having to re-implement the default behavior by hand":
> - what code would you write which preserves the behavior except that it
>   logs all calls to some global variable?
> - what code would you write which preserves the behavior except that it
>   returns nil for one specific buffer?

Here, everything you write in a non-default implementation belongs to
the new functionality; the original functionality is a constant value
returned unconditionally, and it's trivial to write.

> Regarding "Also, so as to make sure that it is *possible* to reimplement
> the default behavior by hand": in my experience trying to change
> *-function to default to a non-nil value, it often happens that the
> preexisting default behavior *cannot* be implemented faithfully (or
> without a lot of extra gymnastic) because it relies on some local
> variable which is not passed as argument to the predicate.

Once again, the default behavior of a predicate is just t or nil, so I
don't think I understand what you ware talking about here.

> I see what you mean.  Yes, the default behavior ends up moved into its
> own function.  I'm surprised you feel so strongly about it, tho, because
> it never caused me such trouble.
> 
> When debugging a specific execution, I'm usually doing it with Edebug,

Tye need to use a debugger instead of just reading the code is already
a huge annoyance, which tremendously slows down problem-solving, due
to the need to arrange for some reproduction recipe, and then step
through the code.

> And when just reading the code without any specific execution in
> mind, I typically don't look at the value of
> save-some-buffers-default-predicate at all since the code should
> work correctly regardless of that value

Debugging a problem does not necessarily need to consider all possible
values, it typically considers only one -- the one that causes the
problem you are debugging.  So it matters a lot whether you can
understand what happens with that specific value, and indeed what _is_
that value, when the problem hits.  In a vast majority of cases, you
only have the final result in the user report: an error message or
some incorrect output, and need to work your way back from that to the
conditions and the logic which failed.  Each indirection is one more
obstacle in this analysis, and given enough of them the analysis
becomes practically impossible (unless you are already well familiar
with the code in question).



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 17:11               ` Eli Zaretskii
@ 2017-01-28 17:22                 ` Stefan Monnier
  2017-01-28 17:30                   ` Eli Zaretskii
  0 siblings, 1 reply; 33+ messages in thread
From: Stefan Monnier @ 2017-01-28 17:22 UTC (permalink / raw)
  To: emacs-devel

>> I don't see what the form of the return value changes to the problem.
> The default behavior is just the value t or nil, so reproducing the

Sorry, I thought you were saying that the predicate's return value can
only be nil or t, not that the predicate always returns the same value.

Yes, in that case the default behavior is trivial, so it's easy to
reproduce it by hand.  Tho, of course, if that default behavior ever
changes, then your manual reproduction of it will go stale.

I was arguing the general case rather than only the specific case of
save-some-buffers-default-predicate.

>> I see what you mean.  Yes, the default behavior ends up moved into its
>> own function.  I'm surprised you feel so strongly about it, tho, because
>> it never caused me such trouble.
>> When debugging a specific execution, I'm usually doing it with Edebug,
> The need to use a debugger instead of just reading the code is already
> a huge annoyance,

I never felt like the need to run Edebug was caused by such additional
indirections, so while I agree that it's great when I can debug the code
just by reading it, I wouldn't attribute the annoyance of running Edebug
to the kind of guideline I'm advocating.

Anyway, I definitely see what you mean.  I just disagree on the
seriousness of the problem, and on the impact of the guideline on it.


        Stefan




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 17:22                 ` Stefan Monnier
@ 2017-01-28 17:30                   ` Eli Zaretskii
  2017-01-28 17:42                     ` Stefan Monnier
  0 siblings, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 17:30 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Sat, 28 Jan 2017 12:22:48 -0500
> 
> Anyway, I definitely see what you mean.  I just disagree on the
> seriousness of the problem, and on the impact of the guideline on it.

The issue is not serious enough to prevent people from using the
methods you'd like to see, but I question the wisdom of having a
project-wide guidelines to _always_ use them is similar situations.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 17:30                   ` Eli Zaretskii
@ 2017-01-28 17:42                     ` Stefan Monnier
  2017-01-28 17:53                       ` Eli Zaretskii
  2017-01-28 18:41                       ` Change in files.el Mark Oteiza
  0 siblings, 2 replies; 33+ messages in thread
From: Stefan Monnier @ 2017-01-28 17:42 UTC (permalink / raw)
  To: emacs-devel

>> Anyway, I definitely see what you mean.  I just disagree on the
>> seriousness of the problem, and on the impact of the guideline on it.
> The issue is not serious enough to prevent people from using the
> methods you'd like to see, but I question the wisdom of having a
> project-wide guidelines to _always_ use them is similar situations.

I think the benefits are the following:
- (eventually) more consistency, such as knowing that you can use
  `add-function` will work right on any *-predicate or
  *-function variable.
- until recently, it was common for such variables to have a nil
  default value.  Without an active effort to reverse this, we'll always
  end up with such new variables introduced with a nil default value
  (especially since it's very common for new such variables to have
  a trivial default behavior, and only accumulating complexity later
  on, at which point it's a lot more difficult to change the default to
  be non-nil).


        Stefan




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 17:42                     ` Stefan Monnier
@ 2017-01-28 17:53                       ` Eli Zaretskii
  2017-01-29 18:59                         ` John Wiegley
  2017-01-28 18:41                       ` Change in files.el Mark Oteiza
  1 sibling, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 17:53 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Sat, 28 Jan 2017 12:42:22 -0500
> 
> > The issue is not serious enough to prevent people from using the
> > methods you'd like to see, but I question the wisdom of having a
> > project-wide guidelines to _always_ use them is similar situations.
> 
> I think the benefits are the following:
> - (eventually) more consistency, such as knowing that you can use
>   `add-function` will work right on any *-predicate or
>   *-function variable.
> - until recently, it was common for such variables to have a nil
>   default value.  Without an active effort to reverse this, we'll always
>   end up with such new variables introduced with a nil default value
>   (especially since it's very common for new such variables to have
>   a trivial default behavior, and only accumulating complexity later
>   on, at which point it's a lot more difficult to change the default to
>   be non-nil).

I'm saying that the benefits do not necessarily outweigh the
downsides, at least IME.  And since the goal of having this
consistently everywhere is not really achievable in practice, given
our development and maintenance procedures, we are buying
disadvantages on account of an advantage that will never materialize.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 17:42                     ` Stefan Monnier
  2017-01-28 17:53                       ` Eli Zaretskii
@ 2017-01-28 18:41                       ` Mark Oteiza
  2017-01-28 19:37                         ` Eli Zaretskii
  1 sibling, 1 reply; 33+ messages in thread
From: Mark Oteiza @ 2017-01-28 18:41 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> Anyway, I definitely see what you mean.  I just disagree on the
>>> seriousness of the problem, and on the impact of the guideline on it.
>> The issue is not serious enough to prevent people from using the
>> methods you'd like to see, but I question the wisdom of having a
>> project-wide guidelines to _always_ use them is similar situations.
>
> I think the benefits are the following:
> - (eventually) more consistency, such as knowing that you can use
>   `add-function` will work right on any *-predicate or
>   *-function variable.
> - until recently, it was common for such variables to have a nil
>   default value.  Without an active effort to reverse this, we'll always
>   end up with such new variables introduced with a nil default value
>   (especially since it's very common for new such variables to have
>   a trivial default behavior, and only accumulating complexity later
>   on, at which point it's a lot more difficult to change the default to
>   be non-nil).

Wasn't the reason any of these defaults changed simply so that
add-function would work?

Having the default be ignore suggests that one can/should always funcall a
FOO-function, and its arguments (should it have any) will be evaluated.
In order to avoid this we now have to check (as is the case in eldoc) if
FOO-function is equal to nil or ignore.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 18:41                       ` Change in files.el Mark Oteiza
@ 2017-01-28 19:37                         ` Eli Zaretskii
  2017-02-01  3:49                           ` Mark Oteiza
  0 siblings, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-01-28 19:37 UTC (permalink / raw)
  To: Mark Oteiza; +Cc: monnier, emacs-devel

> From: Mark Oteiza <mvoteiza@udel.edu>
> Date: Sat, 28 Jan 2017 13:41:31 -0500
> Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org
> 
> Wasn't the reason any of these defaults changed simply so that
> add-function would work?

Why is it important to support add-function, when we already have a
variable that can be assigned a function value?  If someone wants to
customize the feature which will call a variable's value if non-nil,
they just need to write a function which does what they want and
assign it to that variable, no need for add-function.  What am I
missing?



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 14:40     ` Stefan Monnier
  2017-01-28 14:57       ` Eli Zaretskii
@ 2017-01-29  0:21       ` Richard Stallman
  1 sibling, 0 replies; 33+ messages in thread
From: Richard Stallman @ 2017-01-29  0:21 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: eliz, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > - So that you don't have to wrap each and every use inside an `if'.

But...that use is already inside an `if'.
This is the default for an argument which already can be nil.

  > - Or so you don't have to fix the docstring to say what happens when the
  >   value is nil.

I don't think it is necessary.

  > - Or so you can use `add-function' on it.

But you can't do that anyway.

  > - More generally, so that you can slightly change its behavior without
  >   having to re-implement the default behavior by hand.

But `save-some-buffers' already implements the default behavior,
since 1984.

  > - Also, so as to make sure that it is *possible* to reimplement the
  >   default behavior by hand (i.e. to make sure the predicate has access to all
  >   the info it needs to reproduce the default behavior).

I don't think it is worth doing this much extra work
merely to introduce a default value for the argument PRED.

-- 
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 17:53                       ` Eli Zaretskii
@ 2017-01-29 18:59                         ` John Wiegley
  2017-01-30  3:57                           ` Leo Liu
  0 siblings, 1 reply; 33+ messages in thread
From: John Wiegley @ 2017-01-29 18:59 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Stefan Monnier, emacs-devel

>>>>> "EZ" == Eli Zaretskii <eliz@gnu.org> writes:

EZ> I'm saying that the benefits do not necessarily outweigh the downsides, at
EZ> least IME. And since the goal of having this consistently everywhere is
EZ> not really achievable in practice, given our development and maintenance
EZ> procedures, we are buying disadvantages on account of an advantage that
EZ> will never materialize.

I have to say that Eli makes a compelling point here.  Even if we mandate it
today, we incur the job of keeping a constant look out for people violating
this rule forever more, since there is no way to implicitly require it.

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-29 18:59                         ` John Wiegley
@ 2017-01-30  3:57                           ` Leo Liu
  2017-01-30 15:58                             ` John Wiegley
  0 siblings, 1 reply; 33+ messages in thread
From: Leo Liu @ 2017-01-30  3:57 UTC (permalink / raw)
  To: emacs-devel

On 2017-01-29 10:59 -0800, John Wiegley wrote:
> I have to say that Eli makes a compelling point here.  Even if we mandate it
> today, we incur the job of keeping a constant look out for people violating
> this rule forever more, since there is no way to implicitly require it.

This is not something new today. The efforts have been going on for a
while. I think it is good practice as well. For a variable named with
-predicate or -function it would be a surprise if it were not a
function.

Leo




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-30  3:57                           ` Leo Liu
@ 2017-01-30 15:58                             ` John Wiegley
  2017-01-31  4:19                               ` Leo Liu
  2017-01-31 14:46                               ` Stefan Monnier
  0 siblings, 2 replies; 33+ messages in thread
From: John Wiegley @ 2017-01-30 15:58 UTC (permalink / raw)
  To: Leo Liu; +Cc: emacs-devel

>>>>> "LL" == Leo Liu <sdl.web@gmail.com> writes:

LL> This is not something new today. The efforts have been going on for a
LL> while. I think it is good practice as well. For a variable named with
LL> -predicate or -function it would be a surprise if it were not a function.

Can add-function infer that a -function variable with a value of "nil" is
equivalent to it having a value of 'ignore?

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-30 15:58                             ` John Wiegley
@ 2017-01-31  4:19                               ` Leo Liu
  2017-01-31 14:01                                 ` John Wiegley
  2017-01-31 14:46                               ` Stefan Monnier
  1 sibling, 1 reply; 33+ messages in thread
From: Leo Liu @ 2017-01-31  4:19 UTC (permalink / raw)
  To: emacs-devel

On 2017-01-30 10:58 -0500, John Wiegley wrote:
> Can add-function infer that a -function variable with a value of "nil" is
> equivalent to it having a value of 'ignore?

It doesn't make sense for add-function to default to #'ignore. In many
cases `nil' of these variables doesn't mean #'ignore.

Leo




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-31  4:19                               ` Leo Liu
@ 2017-01-31 14:01                                 ` John Wiegley
  0 siblings, 0 replies; 33+ messages in thread
From: John Wiegley @ 2017-01-31 14:01 UTC (permalink / raw)
  To: Leo Liu; +Cc: emacs-devel

>>>>> "LL" == Leo Liu <sdl.web@gmail.com> writes:

LL> On 2017-01-30 10:58 -0500, John Wiegley wrote:
>> Can add-function infer that a -function variable with a value of "nil" is
>> equivalent to it having a value of 'ignore?

LL> It doesn't make sense for add-function to default to #'ignore. In many
LL> cases `nil' of these variables doesn't mean #'ignore.

I see, that is a bit unfortunate. The value of having a default would be to
know what the default behavior is, without having to track down the logic.

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-30 15:58                             ` John Wiegley
  2017-01-31  4:19                               ` Leo Liu
@ 2017-01-31 14:46                               ` Stefan Monnier
  2017-01-31 16:21                                 ` Kaushal Modi
  1 sibling, 1 reply; 33+ messages in thread
From: Stefan Monnier @ 2017-01-31 14:46 UTC (permalink / raw)
  To: emacs-devel

> Can add-function infer that a -function variable with a value of "nil" is
> equivalent to it having a value of 'ignore?

As Leo pointed out, in 99% of the cases, nil is not equivalent to
`ignore' in those variables.  And if it were, then what would be the
benefit to use nil instead of using `ignore' as the default value?


        Stefan




^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-31 14:46                               ` Stefan Monnier
@ 2017-01-31 16:21                                 ` Kaushal Modi
  2017-01-31 18:40                                   ` Default value of variables named `*-function' [was: Change in files.el] Drew Adams
  0 siblings, 1 reply; 33+ messages in thread
From: Kaushal Modi @ 2017-01-31 16:21 UTC (permalink / raw)
  To: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 731 bytes --]

Just a data point from a user:

I would appreciate the consistency of variables named with
-function/-predicate suffixes to have a function has a default value. Being
able to use add-function on just variables is very convenient (I use it to
tweak region-extract-function). The default values also serve as good
examples.

On Tue, Jan 31, 2017 at 10:54 AM Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

> Can add-function infer that a -function variable with a value of "nil" is
> equivalent to it having a value of 'ignore?

As Leo pointed out, in 99% of the cases, nil is not equivalent to
`ignore' in those variables.  And if it were, then what would be the
benefit to use nil instead of using `ignore' as the default value?

[-- Attachment #2: Type: text/html, Size: 1435 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Default value of variables named `*-function'    [was: Change in files.el]
  2017-01-31 16:21                                 ` Kaushal Modi
@ 2017-01-31 18:40                                   ` Drew Adams
  2017-02-01  8:35                                     ` Andreas Röhler
  0 siblings, 1 reply; 33+ messages in thread
From: Drew Adams @ 2017-01-31 18:40 UTC (permalink / raw)
  To: Kaushal Modi, Stefan Monnier, emacs-devel

> I would appreciate the consistency of variables named
> with -function/-predicate suffixes to have a function
> has a default value. Being able to use add-function on
> just variables is very convenient (I use it to tweak
> region-extract-function). The default values also serve
> as good examples.

My comment here is not about providing an implicit/automatic
default value.  (I doubt that that is needed or a good idea,
but I could be wrong.)

My comment is that the default value for a given variable
whose value is intended to be a (single) function _should
usually_ be function `ignore'.  Not implicitly (see previous
paragraph) but explicitly: (defvar foo-function 'ignore).

TL;DR:
Start `-function' vars out with value `ignore', possibly
advised, so `remove-function' can get you back to a no-op.

But please read on...

If the default value needs to be a function that does
something (which is common), then instead of using, as
the default value, the function that provides the default
behavior, use `ignore' as the default value AND advise it
immediately with the function that provides the default
behavior.

Why?  Because then you can use `remove-function' to get
a no-op.  You need not set or bind the variable to
'ignore' to do that; just repeated `remove-function'
will get you to the no-op `ignore'.

`remove-function' is analogous to setting a cons-valued 
variable to its cdr.  If `(cdr (last xs))' is not nil
then xs is not a true list (it is dotted).  Using
`ignore' as the starting point for function advice is like 
using () as the starting point (the last cdr) of a list.
Function  `ignore' is more or less to advice what () is to
a list of functions - an identity element.

Advising the function that is the value of a `*-function'
variable gives you the possibility of, in effect,
applying any number of functions.  Using `:after-while'
or `:before-until', for example, gives you much the same
effect as you get with a normal or abnormal hook (as
opposed to a `*-function' hook).

But there is this big difference between a hook whose
value is a list of functions (a la `add-hook') and a
`*-function' variable whose value is a function that is
advised with, say, `:after-while':

With a hook that is a list of functions, you can remove
them all using `remove-hook'.  With an advised function,
the value is always a function.  You can of course
change the value to `ignore', but you cannot, just using
`remove-function', get to a no-op function.

Unless, that is, the starting point (the default value)
is `ignore'.  Hence my suggestion: Start with `ignore',
advising it immediately if some default behavior is
called for.

That lets users and code use just `add-function' and
`remove-function' to get the effect they have with
`add-hook' and `remove-hook': a (possibly empty)
sequence of functions applied in order.

I pointed this out in a parenthical remark in this post:
http://lists.gnu.org/archive/html/emacs-devel/2016-10/msg00415.html

    (Note that one difference from a hook is that a hook
    does not privilege the first hook function in any way
    (or the last, depending on how you look at it).
    Removing advice is not equivalent to `remove-hook'.
    It never "empties the hook" completely - the function
    that was advised is still there after removal of all
    advice.)

Here's a case in point:

Variable `isearch-filter-predicate' has a function value
or nil.  This is legacy.  Users and code can still bind
it or set it to nil.

But they cannot set it to a list of functions.  IOW, it
is basically a single-function variable (which would
normally be named `*-function') - except for the ability
to use nil instead.

I have code that lets you (interactively) add to, remove
from, etc. the behavior of `isearch-filter-predicate' on
the fly.  For more info, see
https://www.emacswiki.org/emacs/DynamicIsearchFiltering.

You can hit a key to change the current filter predicate
in ways like these:

C-z -   Remove a predicate that you specify (default:
        last-added predicate).
C-z &   Add a predicate, AND-ing it as an `:after-while'
        filter.
C-z %   Add a predicate that requires search hits to
        match a regexp you provide.
C-z ||  Add a predicate, OR-ing it as a `:before-until'
        filter.
C-z |1  Replace the last-added filter by OR-ing it with
        another.
C-z ~~  Complement the overall filter predicate.
C-z ~1  Replace the last-added filter by its complement.
C-z !   Set the overall filter predicate.
C-z 0   Reset the overall filter predicate to its default
        value (`isearch-filter-visible').
C-z c   Add a predicate that limits search between two
        columns that you specify.
C-z @   Add a predicate that constrains searching within a 
        given distance of (near) another search pattern
        (you specify the distance and pattern).

Since the default value of `isearch-filter-predicate' is
not `ignore' but `isearch-filter-visible', you cannot just
add and remove advice to get a no-op behavior or a behavior
that is not a modification of `isearch-filter-visible'.
Instead, you must set (or bind) `isearch-filter-predicate'.

This is a defect, resulting from legacy: (1) using nil
instead of `ignore' as the no-op filter and (2) using
`isearch-filter-visible' instead of `ignore' as the
default filter.

It would be nice to be able to just add & remove advice,
to control the behavior.  But that always acts on
function `isearch-filter-visible', not on `ignore'.

Code should of course be _able_ to set or bind the
variable value - no question about that.  But things
are more flexible if you can _also_ do pretty much
anything to modify the behavior using just advice.

If my suggestion were applied to the case of
`isearch-filter-predicate' then (1) it would be renamed
(e.g., to `isearch-filter-function'), and (2) its
default value would be `ignore'.

Now, because `isearch-filter-predicate' is legacy,
(1) the variable renaming would need to deprecate (but
continue to support) the old name, and (2) the variable
value nil would need to continue to be supported.

This is just an example, to try to get across the
suggestion that (1) we use `ignore' as the (explicit,
not automatic/implied) default value of variables named
`*-function', and (2) for any such variable whose
default behavior needs to be a no-op, we immediately
(i.e., by default) advise it to provide that default
behavior.

That gives users & code two ways to change it to a no-op:
(a) set the variable value to `ignore' or (b) remove all
advice from the default function (`ignore').

In a way, this amounts to saying that what is said
(correctly) in (elisp) `Advice combinators' about
various kinds of advice being "comparable for
single-function hooks to (add-hook..." is not also true
for `remove-function' - unless the starting point is
function `ignore'.  Repeatedly applying `remove-hook'
will eventually get you to (), but repeatedly applying
`remove-function' will not get you to `ignore', unless...

You might point out that if a user or code _does_ just
set the value of such a variable to some other function
than `ignore' then `remove-function' will _not_ get back
to `ignore'.  Clearly.  The effect of setting or (with a
little more work) binding can be had using just advice,
but nothing prevents someone from not using advice to
change the value.

Dunno whether I was clear or I am missing something
important.  But WDOT?



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28 19:37                         ` Eli Zaretskii
@ 2017-02-01  3:49                           ` Mark Oteiza
  2017-02-01  7:33                             ` Clément Pit-Claudel
  0 siblings, 1 reply; 33+ messages in thread
From: Mark Oteiza @ 2017-02-01  3:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: monnier, emacs-devel

On 28/01/17 at 09:37pm, Eli Zaretskii wrote:
> > From: Mark Oteiza <mvoteiza@udel.edu>
> > Date: Sat, 28 Jan 2017 13:41:31 -0500
> > Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org
> > 
> > Wasn't the reason any of these defaults changed simply so that
> > add-function would work?
> 
> Why is it important to support add-function, when we already have a
> variable that can be assigned a function value?  If someone wants to
> customize the feature which will call a variable's value if non-nil,
> they just need to write a function which does what they want and
> assign it to that variable, no need for add-function.  What am I
> missing?

You're not missing anything.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-02-01  3:49                           ` Mark Oteiza
@ 2017-02-01  7:33                             ` Clément Pit-Claudel
  2017-02-01 12:56                               ` Eli Zaretskii
  0 siblings, 1 reply; 33+ messages in thread
From: Clément Pit-Claudel @ 2017-02-01  7:33 UTC (permalink / raw)
  To: Mark Oteiza, Eli Zaretskii; +Cc: monnier, emacs-devel

On 2017-01-31 22:49, Mark Oteiza wrote:
> On 28/01/17 at 09:37pm, Eli Zaretskii wrote:
>> What am I missing?
> 
> You're not missing anything.

Well, it's not uncommon to want to extend existing behavior, and add-function lets you do it easily — more easily than if the variable may be nil.






^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Default value of variables named `*-function' [was: Change in files.el]
  2017-01-31 18:40                                   ` Default value of variables named `*-function' [was: Change in files.el] Drew Adams
@ 2017-02-01  8:35                                     ` Andreas Röhler
  0 siblings, 0 replies; 33+ messages in thread
From: Andreas Röhler @ 2017-02-01  8:35 UTC (permalink / raw)
  To: emacs-devel; +Cc: Drew Adams



On 31.01.2017 19:40, Drew Adams wrote:
>> I would appreciate the consistency of variables named
>> with -function/-predicate suffixes to have a function
>> has a default value. Being able to use add-function on
>> just variables is very convenient (I use it to tweak
>> region-extract-function). The default values also serve
>> as good examples.
> My comment here is not about providing an implicit/automatic
> default value.  (I doubt that that is needed or a good idea,
> but I could be wrong.)
>
> My comment is that the default value for a given variable
> whose value is intended to be a (single) function _should
> usually_ be function `ignore'.  Not implicitly (see previous
> paragraph) but explicitly: (defvar foo-function 'ignore).
>
> TL;DR:
> Start `-function' vars out with value `ignore', possibly
> advised, so `remove-function' can get you back to a no-op.
>
> But please read on...
>
> If the default value needs to be a function that does
> something (which is common), then instead of using, as
> the default value, the function that provides the default
> behavior, use `ignore' as the default value AND advise it
> immediately with the function that provides the default
> behavior.
>
> Why?  Because then you can use `remove-function' to get
> a no-op.  You need not set or bind the variable to
> 'ignore' to do that; just repeated `remove-function'
> will get you to the no-op `ignore'.
>
> `remove-function' is analogous to setting a cons-valued
> variable to its cdr.  If `(cdr (last xs))' is not nil
> then xs is not a true list (it is dotted).  Using
> `ignore' as the starting point for function advice is like
> using () as the starting point (the last cdr) of a list.
> Function  `ignore' is more or less to advice what () is to
> a list of functions - an identity element.
>
> Advising the function that is the value of a `*-function'
> variable gives you the possibility of, in effect,
> applying any number of functions.  Using `:after-while'
> or `:before-until', for example, gives you much the same
> effect as you get with a normal or abnormal hook (as
> opposed to a `*-function' hook).
>
> But there is this big difference between a hook whose
> value is a list of functions (a la `add-hook') and a
> `*-function' variable whose value is a function that is
> advised with, say, `:after-while':
>
> With a hook that is a list of functions, you can remove
> them all using `remove-hook'.  With an advised function,
> the value is always a function.  You can of course
> change the value to `ignore', but you cannot, just using
> `remove-function', get to a no-op function.
>
> Unless, that is, the starting point (the default value)
> is `ignore'.  Hence my suggestion: Start with `ignore',
> advising it immediately if some default behavior is
> called for.
>
> That lets users and code use just `add-function' and
> `remove-function' to get the effect they have with
> `add-hook' and `remove-hook': a (possibly empty)
> sequence of functions applied in order.
>
> I pointed this out in a parenthical remark in this post:
> http://lists.gnu.org/archive/html/emacs-devel/2016-10/msg00415.html
>
>      (Note that one difference from a hook is that a hook
>      does not privilege the first hook function in any way
>      (or the last, depending on how you look at it).
>      Removing advice is not equivalent to `remove-hook'.
>      It never "empties the hook" completely - the function
>      that was advised is still there after removal of all
>      advice.)
>
> Here's a case in point:
>
> Variable `isearch-filter-predicate' has a function value
> or nil.  This is legacy.  Users and code can still bind
> it or set it to nil.
>
> But they cannot set it to a list of functions.  IOW, it
> is basically a single-function variable (which would
> normally be named `*-function') - except for the ability
> to use nil instead.
>
> I have code that lets you (interactively) add to, remove
> from, etc. the behavior of `isearch-filter-predicate' on
> the fly.  For more info, see
> https://www.emacswiki.org/emacs/DynamicIsearchFiltering.
>
> You can hit a key to change the current filter predicate
> in ways like these:
>
> C-z -   Remove a predicate that you specify (default:
>          last-added predicate).
> C-z &   Add a predicate, AND-ing it as an `:after-while'
>          filter.
> C-z %   Add a predicate that requires search hits to
>          match a regexp you provide.
> C-z ||  Add a predicate, OR-ing it as a `:before-until'
>          filter.
> C-z |1  Replace the last-added filter by OR-ing it with
>          another.
> C-z ~~  Complement the overall filter predicate.
> C-z ~1  Replace the last-added filter by its complement.
> C-z !   Set the overall filter predicate.
> C-z 0   Reset the overall filter predicate to its default
>          value (`isearch-filter-visible').
> C-z c   Add a predicate that limits search between two
>          columns that you specify.
> C-z @   Add a predicate that constrains searching within a
>          given distance of (near) another search pattern
>          (you specify the distance and pattern).
>
> Since the default value of `isearch-filter-predicate' is
> not `ignore' but `isearch-filter-visible', you cannot just
> add and remove advice to get a no-op behavior or a behavior
> that is not a modification of `isearch-filter-visible'.
> Instead, you must set (or bind) `isearch-filter-predicate'.
>
> This is a defect, resulting from legacy: (1) using nil
> instead of `ignore' as the no-op filter and (2) using
> `isearch-filter-visible' instead of `ignore' as the
> default filter.
>
> It would be nice to be able to just add & remove advice,
> to control the behavior.  But that always acts on
> function `isearch-filter-visible', not on `ignore'.
>
> Code should of course be _able_ to set or bind the
> variable value - no question about that.  But things
> are more flexible if you can _also_ do pretty much
> anything to modify the behavior using just advice.
>
> If my suggestion were applied to the case of
> `isearch-filter-predicate' then (1) it would be renamed
> (e.g., to `isearch-filter-function'), and (2) its
> default value would be `ignore'.
>
> Now, because `isearch-filter-predicate' is legacy,
> (1) the variable renaming would need to deprecate (but
> continue to support) the old name, and (2) the variable
> value nil would need to continue to be supported.
>
> This is just an example, to try to get across the
> suggestion that (1) we use `ignore' as the (explicit,
> not automatic/implied) default value of variables named
> `*-function', and (2) for any such variable whose
> default behavior needs to be a no-op, we immediately
> (i.e., by default) advise it to provide that default
> behavior.
>
> That gives users & code two ways to change it to a no-op:
> (a) set the variable value to `ignore' or (b) remove all
> advice from the default function (`ignore').
>
> In a way, this amounts to saying that what is said
> (correctly) in (elisp) `Advice combinators' about
> various kinds of advice being "comparable for
> single-function hooks to (add-hook..." is not also true
> for `remove-function' - unless the starting point is
> function `ignore'.  Repeatedly applying `remove-hook'
> will eventually get you to (), but repeatedly applying
> `remove-function' will not get you to `ignore', unless...
>
> You might point out that if a user or code _does_ just
> set the value of such a variable to some other function
> than `ignore' then `remove-function' will _not_ get back
> to `ignore'.  Clearly.  The effect of setting or (with a
> little more work) binding can be had using just advice,
> but nothing prevents someone from not using advice to
> change the value.
>
> Dunno whether I was clear or I am missing something
> important.  But WDOT?
>

+1

OTOH wondering if not a simple customizable listing of 
buffers-not-to-save/query would deliver all needed.
Reading doc-string of optional arg PRED -- isn't that already kind of 
over-engineered?



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-02-01  7:33                             ` Clément Pit-Claudel
@ 2017-02-01 12:56                               ` Eli Zaretskii
  2017-02-01 14:12                                 ` Kaushal Modi
  0 siblings, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-02-01 12:56 UTC (permalink / raw)
  To: Clément Pit-Claudel; +Cc: mvoteiza, monnier, emacs-devel

> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
> From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> Date: Wed, 1 Feb 2017 02:33:14 -0500
> 
> Well, it's not uncommon to want to extend existing behavior, and add-function lets you do it easily — more easily than if the variable may be nil.

Easier than using setq?  I doubt that.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-02-01 12:56                               ` Eli Zaretskii
@ 2017-02-01 14:12                                 ` Kaushal Modi
  0 siblings, 0 replies; 33+ messages in thread
From: Kaushal Modi @ 2017-02-01 14:12 UTC (permalink / raw)
  To: Eli Zaretskii, Clément Pit-Claudel; +Cc: mvoteiza, monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1536 bytes --]

On Wed, Feb 1, 2017 at 8:14 AM Eli Zaretskii <eliz@gnu.org> wrote:

> > Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
> > From: Clément Pit-Claudel <cpitclaudel@gmail.com>
> > Date: Wed, 1 Feb 2017 02:33:14 -0500
> >
> > Well, it's not uncommon to want to extend existing behavior, and
> add-function lets you do it easily — more easily than if the variable may
> be nil.
>
> Easier than using setq?  I doubt that.
>

Using add-function instead of setq has these advantages:

- You do not need to copy-paste the original variable definition, and
*then* add your tweaks around it. (add-function :around ..) does that for
you. Given that the *-function definitions can be multiple lines long, it
saves some clutter from your emacs config.
- If the variable customization does not work out, or you discovered a bug
in the customization (and you do not have time to debug it), you can remove
that safely using (remove-function ..) and get back the original
definition.. No need to find the original definition and re-eval that.
- If the original definition changes upstream, there are lesser chances of
your config breaking if you did add-function than setq. And if it breaks
due to an upstream change, just do remove-function till you get time to fix
your customization.
- Added convenience that you can edebug your customization function that
you "add" to the original *-function variable. So you debug focuses only on
the customization and not also on the original definition.

-- 

Kaushal Modi

[-- Attachment #2: Type: text/html, Size: 2319 bytes --]

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-01-28  2:16 Change in files.el Richard Stallman
  2017-01-28  2:46 ` Stefan Monnier
@ 2017-02-04  9:18 ` Eli Zaretskii
  2017-02-04 23:52   ` Richard Stallman
  1 sibling, 1 reply; 33+ messages in thread
From: Eli Zaretskii @ 2017-02-04  9:18 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

> From: Richard Stallman <rms@gnu.org>
> Date: Fri, 27 Jan 2017 21:16:05 -0500
> 
> Would someone please install this for me so that I don't have to
> struggle with git?

Done.



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: Change in files.el
  2017-02-04  9:18 ` Eli Zaretskii
@ 2017-02-04 23:52   ` Richard Stallman
  0 siblings, 0 replies; 33+ messages in thread
From: Richard Stallman @ 2017-02-04 23:52 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

Thank you.

I've concluded I have no opinion about the question of whether
...predicate variables should always have a function as value
and never nil.

However, to make that so for this variable will take some work.  If
someone makes this change, please tell me as I will need to change my
own customization.

-- 
Dr Richard Stallman
President, Free Software Foundation (gnu.org, fsf.org)
Internet Hall-of-Famer (internethalloffame.org)
Skype: No way! See stallman.org/skype.html.




^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2017-02-04 23:52 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-28  2:16 Change in files.el Richard Stallman
2017-01-28  2:46 ` Stefan Monnier
2017-01-28  9:10   ` Eli Zaretskii
2017-01-28 14:40     ` Stefan Monnier
2017-01-28 14:57       ` Eli Zaretskii
2017-01-28 15:31         ` Dmitry Gutov
2017-01-28 16:12           ` Eli Zaretskii
2017-01-28 15:40         ` Stefan Monnier
2017-01-28 16:08           ` Eli Zaretskii
2017-01-28 16:51             ` Stefan Monnier
2017-01-28 17:11               ` Eli Zaretskii
2017-01-28 17:22                 ` Stefan Monnier
2017-01-28 17:30                   ` Eli Zaretskii
2017-01-28 17:42                     ` Stefan Monnier
2017-01-28 17:53                       ` Eli Zaretskii
2017-01-29 18:59                         ` John Wiegley
2017-01-30  3:57                           ` Leo Liu
2017-01-30 15:58                             ` John Wiegley
2017-01-31  4:19                               ` Leo Liu
2017-01-31 14:01                                 ` John Wiegley
2017-01-31 14:46                               ` Stefan Monnier
2017-01-31 16:21                                 ` Kaushal Modi
2017-01-31 18:40                                   ` Default value of variables named `*-function' [was: Change in files.el] Drew Adams
2017-02-01  8:35                                     ` Andreas Röhler
2017-01-28 18:41                       ` Change in files.el Mark Oteiza
2017-01-28 19:37                         ` Eli Zaretskii
2017-02-01  3:49                           ` Mark Oteiza
2017-02-01  7:33                             ` Clément Pit-Claudel
2017-02-01 12:56                               ` Eli Zaretskii
2017-02-01 14:12                                 ` Kaushal Modi
2017-01-29  0:21       ` Richard Stallman
2017-02-04  9:18 ` Eli Zaretskii
2017-02-04 23:52   ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).