emacs-devel
[Top][All Lists]
Advanced

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

Re: Proposal: Forwards-Compatibility Library for Emacs


From: Philip Kaludercic
Subject: Re: Proposal: Forwards-Compatibility Library for Emacs
Date: Wed, 22 Sep 2021 09:54:12 +0000

Lars Ingebrigtsen <larsi@gnus.org> writes:

> Richard Stallman <rms@gnu.org> writes:
>
>>   > The idea is to allow developers who don't want to break backwards
>>   > compatibility to use newer functionality that wasn't provided in older
>>   > versions of Emacs. This version tries to implement as much as possible
>>   > from Emacs 24.2 onwards.
>>
>> Would you please state concretely what this package would do?

Functionality-wise: The package uses custom macros to define
"compatibility functions". A compatibility function implements at least
a subset of the behaviour the "real function" would provide, if it were
defined in whatever release of Emacs.

The macros it provides are:

- compat-defun

  Defines a compatibility function that is only aliased to the "real"
  symbol, if this is unbound and the specified version is greater than
  the current version. Example:

        (compat-defun always (&rest _arguments)
          "Do nothing and return t.
        This function accepts any number of ARGUMENTS, but ignores them.
        Also see `ignore'."
          :version "28.1"
          t)

  On Emacs 28.1 an newer, this just expands to `nil', because the plist
  after the documentation sting specifies that this function was defined
  in Emacs 28.1. Other attributes can be given such as part of what
  library this function was defined, so that it is wrapped in an
  eval-after-load body, preventing the developer from using the
  function, without loading the right library beforehand.
  
  Otherwise it defines

        (defun compat--always (&rest _)
          "[Compatibility function for `always', defined in Emacs 28.1]

        Do nothing and return t.
        This function accepts any number of ARGUMENTS, but ignores them.
        Also see `ignore'."
          t)

  followed by

        (unless (fboundp 'always)
          (defalias 'always #'compat-always))

- compat-macro

  Analogous to compat-defun, just for macros.

- compat-advise

  Defines an advice function that is then applied to wrap (ie. :around)
  the actual function. Example:

        (compat-advise sort (seq predicate)
          "Handle SEQ of type vector."
          :version "25.1"
          (cond
           ((listp seq)
            (funcall oldfun seq predicate))
           ((vectorp seq)
            (let ((cseq (sort (append seq nil) predicate)))
              (dotimes (i (length cseq))
                (setf (aref seq i) (nth i cseq)))
              (apply #'vector cseq)))
           ((signal 'wrong-type-argument 'list-or-vector-p))))

   Again, it defines a compat--sort function with the same body as
   compat-advise, and an additional argument "oldfun".

- compat-defvar

  Defines a variable, constant, buffer-local or permanent-local
  variable, again using a version attribute and boundp to check if it
  should do so.

I plan to add at least compat-defface, for defining faces that older
versions of Emacs didn't provide.

> The library defines versions of newer functions if Emacs doesn't already
> have them.  For instance, Emacs 28 has a new function
> 'buffer-local-boundp'.  Philip's library would provide a definition of
> functions like that for use in ELPA code that's written for newer Emacs
> versions, so that they can be used in older Emacs versions without
> introducing compatibility shims like `foo-package-buffer-local-boundp'.
>
> This also allows us to put (more) core packages into GNU ELPA without
> any code changes.

I am not sure if no-code-changes are always possible, but that would be
the best-case scenario.

>>   > By its very nature it is an intrusive package, as it defines functions,
>>   > macros and advice outside of the "namespace", but I don't see any way
>>   > around that if transparent compatibility is to be provided (anything
>>   > else would just replicate dash, s, f, ...).
>>
>> I have a plan to put those names into optional namespaces (using
>> symbol renaming) so that the entry points of those packages will
>> be visible only from packages that require specific libraries.
>
> Philip shouldn't have mentioned s and dash and the rest -- his proposal
> has absolutely nothing to do with those, but it seems like many people
> have lashed onto that part, somehow.

The reason I mentioned these libraries at all, is that for more than a
few package developers, I have noticed that they use these libraries for
the sake of convenience *and* backwards compatibility. As these
libraries are updated externally, they provide more easily usable
functionality that wasn't given in say Emacs 24.x. If they are
interested in convince and less repetitive programming, as I am sure
many are, they would have to choose between raising the minimal version
required to use their package or to add these external libraries.

My point in mentioning these was not to give a direct comparison, but
just to say that if compat.el didn't use transparent compatibility, it
would just become another utility function library -- just instead of
using a Clojure style of programming, it would stick to the more
traditional Elisp conventions.

-- 
        Philip Kaludercic



reply via email to

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