Subject: RE: bug#33601: 26; Add macro `with-hook-added'

From: Drew Adams <[email-masked]>
Date: Tue, 4 Dec 2018 13:22:41 -0800 (PST)

> > > Just a big point: you need to test whether FUNCTION is already on
> > > HOOK at the start, and if so, not remove it at the end.
> 
> > A big point?  Need to?
> 
> I think so, yes.  The essence of the `with-...' macros is that they
> temporarily change something, then evaluate ,@body, and at the end, the
> something is restored to what it was.
> 
> If with-hook-added didn't preserve the hook, it would
> be an anomaly, an outlier, and quite possibly a PITA.

If there's an unwritten rule that `with-*' macros
preserve and restore everything then clearly the
macro I proposed was not a `with-*' macro.  Another
name for it would be fine, if that's the rule. ;-)

> > That wasn't the behavior I had in mind for this, but it's
> > another possibility.  I intended to provide only for the
> > behavior of always removing at the end.
> 
> Why?  What's the use case?

The kind of thing I showed (with two examples).

Yes, I would use them where I either know that the
function is not on the hook already or I don't
care - cases where I would want it removed at the
end in any case.

And yes, given your question, the doc of such a
macro would need to make clear that it always
removes FUNCTION from the hook afterward.

> > Choices:
> > 1. Provide a single macro for all such possibilities, with
> >    3 (mandatory) args for APPEND, LOCAL and whether to remove
> >    FUNCTION at the end if it was already present at the outset.
> > 2. Provide multiple macros, each specific for a given case.
> >
> > #2 would mean 8 macros, to cover all the combinations
> > (nil or t for each of the 3 args).
> 
> How many of these would actually be of any use?

All of the behaviors are useful.  If you meant to ask
whether it is useful to have 8 individual macros, then
my answer is probably not.

> > Another possibility would be to accept a single arg for
> > the BODY code, instead of that being a &rest parameter,
> > and so be able to provide those 3 behavior-specifying
> > args as optional.  In that case, we'd want to decide on
> > the best order among those args, e.g., based on which we
> > expect to be used most often.
> 
> > I'm not sure what the right approach is.  I think the
> > most common use case would be the one I wrote up (but
> > I don't know that):
> >
> > . Always remove FUNCTION at the end
> > . Prepend, not append.
> > . Global, not local.

I really have no problem with what you requested:
not removing FUNCTION at the end if it was present
beforehand.

However, now you've gone beyond that to suggest
that we should restore the original hook value:
"preserve the hook".

Should it preserve the hook?  Maybe, maybe not.

How strict is your unwritten `with-*' rule?  Does
it apply only to undoing the particular change _it_
makes, or does it also undo changes that might be
made by the BODY?  In this case, the BODY might
itself make changes to the hook.

If I had to choose only one macro, it would
probably be a general one.  I guess it would, as
you first requested, remove FUNCTION only if it
was not already present.  And it would accept
args for APPEND and LOCAL.  But it would not
restore the original hook value.

Whether it should require args APPEND and LOCAL
or it should instead make you wrap body sexps in
a progn is another choice.  Dunno which I'd prefer,
but probably the former (probably less error prone).

Other ideas are welcome.  What is your preference
(besides always restoring the original hook value)?