Subject: bug#21563: 24.5; discourage load-hook variables

From: Drew Adams <[email-masked]>
Date: Wed, 15 Jan 2020 19:56:09 -0800 (PST)

> > I don't have a giant objection to doing what you're talking
> > about doing.  But I think it's unfortunate, and little, if
> > anything, is really gained.
> 
> Well, Emacs is old.  Like any old software, it has a certain amount of
> cruft and/or historical accidents.  Getting rid of such things when we
> can makes Emacs easier to maintain in the long run.

So is the argument now that the existence of load
hooks makes maintenance too complicated?  What will
be the next argument?

`eval-after-load' is at least as old as load hooks.
Probably both have been there since about Day One.
Maybe ask RMS why.  Maybe load hooks are just cruft,
or maybe not.

> > Who knows what 3rd-party code out there makes use of such hooks?
> 
> It should migrate to use (with-)eval-after-load.  That should be
> backwards compatible through "Emacs version 19.29" according to C-h f.

Why should it migrate?  That's my question.  Why is
it good now to toss load hooks, when that hasn't been
needed before?  40 years of Emacs, and now there's a
reason to toss them.  What's so important about this
now?  A bug filed because someone set a hook too late
in his init file?  If that were a big problem, don't
you think load hooks would have been removed long ago?

> Note that the way these hooks have been obsoleted by Glenn is to still
> run them if they exist, but add an obsoletion warning.  I think this
> is the correct approach.
> 
> Given how long it takes for us to finally delete obsolete stuff, that
> should give ten years, give or take, before any third party code
> depending on these hooks would stop working.

Why delete them at all, finally or immediately?  What's
the real point?  The only thing new (and that's several
years old now) was the addition of `with-eval-after-load'
(because some users were forgetting that `eval-after-load'
is a function, and so evaluates its args).

> > And again, they're easy for users to discover.
> 
> I think a general facility is even more discoverable and user
> friendly.  In particular, it shows users that this could be used for
> any package, and not just packages which has defined a particular
> hook.

The two aren't the same, as I pointed out.  And see
what I said earlier about discoverability.

A hook named after a feature draws your attention to
the possibility of hooking in some code there - at
that spot, for that feature.  A general facility to
eval some code after loading a file, any file, isn't
quite the same, in particular in terms of notice
(discoverability).

> > And I think they're likely to be used by code, and not just in init
> > files.  That's not so true of `(with-)?eval-after-load' (explicitly
> > discouraged).
> 
> Shouldn't use of these hooks in code be considered bad practice for
> the same reasons that eval-after-load is?

Dunno.  Why so?  They haven't been introduced at the
end of every single library.  Someone presumably had
a reason for introducing each one, or at least most.

A hook is an explicit signal that you kinda expect
someone (some code) to want to hook in some other code
at that spot.  A hook is an invitation: "Here's a
place you might want to do something."  There are no
doubt specific hooks that no one has ever used and
that could perhaps be removed.  But why do so?

Many load hooks are even user options (I don't argue
they should be).  Users who've customized them will
eventually find that they've become no-ops.
`dired-load-hook', for example, has this added to its
doc string, to tell you about possible use cases:
"You can customize key bindings or load extensions with this."

Why do we still have _any_ hooks?  Why not argue
(maybe someone will - Stefan?) that nadvice makes all
other hooks obsolete.

Anyway, as I say, I don't care much, if no one else
cares about this.

Please be sure to take care of all places that might
take such hooks into consideration.  This comment in
dired-x.el, for example (no idea whether it's important):

;; This is a no-op if dired-x is being loaded via `dired-load-hook',
;; but maybe not if a dired-x function is being autoloaded.
(require 'dired)

And there are some hooks with `-load-hook' in the name
that don't seem to be hooks run after loading a file.
`ff-pre-load-hook' and `ff-post-load-hook', for example.
For them, "loading" a file apparently means something
quite different (if so, that's a naming bug).  And they
are buffer-local variables.