[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: How to find when a feature was introduced

From: Drew Adams
Subject: RE: How to find when a feature was introduced
Date: Fri, 8 Jul 2016 16:40:43 +0000 (UTC)

> I see too many libraries (IMHO) that evolve to gratuitously use
> recent constructs, which means some of their users can lose the
> possibility of using them.
> By "gratuitously" here I mean that the library maintainer and the
> library itself do not really gain anything important by such a
> change.  Obviously, if a new feature enables you to do something
> really different (e.g. bidi support) or really better, then there
> is no reason not to take advantage of it.
> But many changes I see are little more than cosmetic, and if such
> a case throws library users by the wayside then I think that's a
> waste.  On the other hand, it can make things easier for a library
> maintainer not to have to worry about supporting more than the
> latest release...

And to circle back to the original question and its use case:
Choosing to use macro `with-eval-after-load' instead of function
`eval-after-load' is a good example of an evolution for a
library to undergo that is often essentially gratuitous, IMO.

If there is another, better or significant reason to require
a version of Emacs that is recent enough that it includes
`with-eval-after-load', then using that macro is _not_ just
gratuitous.  But on its own, as the sole reason for requiring
that recent a version of Emacs, it is likely to be so.

Here is the definition of macro `with-eval-after-load':

(defmacro with-eval-after-load (file &rest body)
  `(eval-after-load ,file (lambda () ,@body)))

It just wraps the BODY in a lambda and calls `eval-after-load'.
The lambda form is funcalled after FILE is loaded.

Why was this macro added to Emacs?  (Its addition was a good
thing, BTW.)

(1) Because the most common use case of `eval-after-load' passes
a quoted sexp as the BODY, and some users were leaving off the
quote and then wondering why their code did not work.

And (2) because a quoted BODY returns a sexp, and that sexp
(to be evaluated later as code) is just constant _data_ at
compile time; it is not byte-compiled as code.

Both are good reasons for adding `with-eval-after-load' to
Emacs.  Are they good reasons for replacing `eval-after-load'
in your library?

IMO it depends on (a) whether byte-compiling the particular
BODY form really makes a difference for your code and, if not,
(b) whether there is anyway another reason for the library to
be usable only with an Emacs version that is recent enough to
have `with-eval-after-load'.

(And for (a), if the BODY sexp is complex enough that you
care about it being compiled, it is usually enough to just 
define a function that encapsulates that sexp, and use the
function name as BODY.  The function definition is compiled.)

This macro was introduced in Emacs 24.4.  And immediately,
I suspect, libraries all over the place started using it,
even sometimes replacing correct uses of `eval-after-load'.

Are all such updates needed? useful?  Are some of them what
I would call gratuitous?

My own approach is to require Emacs 24.4 or later only when
the code in my library really needs it or can really take
advantage of it.  I generally would not do that just to be
able to use macro `with-eval-after-load'.

As usual, it's a tradeoff: Do you want users with an older
Emacs version to be able to use your library?  Do you want
to take advantage of what the new feature (macro, in this
case) offers?

Sometimes a new library starts out more or less as a set
of personal Emacs customizations.  In that context, the
library author typically does not care about supporting
versions of Emacs older than the one s?he uses.

And that unconcern for older-version use can then become
a habit.  And it certainly is easier, in terms of
maintenance.  I think this explains most lack of support
for multiple Emacs versions.


There is also this consideration, BTW, from (elisp) `Coding
Conventions', but it is orthogonal to my point here.

  Avoid using 'eval-after-load' and 'with-eval-after-load'
  in libraries and packages (*note Hooks for Loading::).
  This feature is meant for personal customizations; using
  it in a Lisp program is unclean, because it modifies the
  behavior of another Lisp file in a way that's not visible
  in that file.  This is an obstacle for debugging, much
  like advising a function in the other package.

That is of course reasonable advice, though it simplifies
and overstates the case.  Running a hook, in this case
after loading a Lisp file, does _not_ necessarily modify
the behavior of that file.  What is true is that whatever
the hook function does is not something that is visible
in that Lisp file.

It's OK - that text is not bad.  But it is a case of a 
recommendation in the doc that you want to _understand_
and not just take literally as gospel.

reply via email to

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