unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Comparing hash table objects
@ 2022-06-08  8:41                     ` Ihor Radchenko
  2022-06-08  8:51                       ` Andreas Schwab
       [not found]                       ` <8734zoaolv.fsf@localhost>
  0 siblings, 2 replies; 20+ messages in thread
From: Ihor Radchenko @ 2022-06-08  8:41 UTC (permalink / raw)
  To: emacs-devel

Hello,

Is there any way to compare objects containing hash tables for equality?

I have a struct that is created like
(list 'type (make-hash-table))
With hash table later populated with some key:value pairs.

I expect two structs like the above to be comparable via equal:
(equal (list 'type (make-hash-table)) (list 'type (make-hash-table))) ;; => t

However, running the above code gives nil.

Is the above behavior intentional?

Best,
Ihor



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

* Re: Comparing hash table objects
  2022-06-08  8:41                     ` Comparing hash table objects Ihor Radchenko
@ 2022-06-08  8:51                       ` Andreas Schwab
  2022-06-08  9:17                         ` Ihor Radchenko
       [not found]                       ` <8734zoaolv.fsf@localhost>
  1 sibling, 1 reply; 20+ messages in thread
From: Andreas Schwab @ 2022-06-08  8:51 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-devel

On Jun 08 2022, Ihor Radchenko wrote:

> Is there any way to compare objects containing hash tables for equality?

Hash tables are only equal if eq.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."



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

* Re: Comparing hash table objects
  2022-06-08  8:51                       ` Andreas Schwab
@ 2022-06-08  9:17                         ` Ihor Radchenko
  2022-06-10 22:45                           ` Richard Stallman
  0 siblings, 1 reply; 20+ messages in thread
From: Ihor Radchenko @ 2022-06-08  9:17 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: emacs-devel

Andreas Schwab <schwab@suse.de> writes:

> On Jun 08 2022, Ihor Radchenko wrote:
>
>> Is there any way to compare objects containing hash tables for equality?
>
> Hash tables are only equal if eq.

This is somewhat unexpected.

To clarify my problem, let me explain in more details what I am trying
to achieve.

Currently, I am using structs to store objects with properties:
(setq obj1 (type (:key1 val1 :key2 val2 ...)))
(setq obj2 (type (:key1 val1 :key2 val2 ...))) ;; the same properties

With this approach, I can easily compare objects with (equal obj1 obj2),
use them as hash table keys, etc.

However, when the number of properties increases, :key access becomes
slow because plist-get has O(N) complexity.

The natural solution is using hash tables:

(setq obj1 (type (make-hash-table)))
(setq obj2 (type (make-hash-table)))
;; fill the hash tables with :keyN valN pairs

Now, I can retrieve the :key in O(1).

However, all of a sudden, I am unable to compare two objects with this
new internal structure. (equal obj1 obj2) returns nil.

The described behavior potentially generates a lot of room for errors.
It is relatively easy to remember that different hash table objects are
never equal (only equal when also eq). However, when the hash tables are
hidden inside a struct, it is easy to overlook that the structs cannot
be compared with equal as usual.

Best,
Ihor




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

* Re: Comparing hash table objects
  2022-06-08  9:17                         ` Ihor Radchenko
@ 2022-06-10 22:45                           ` Richard Stallman
  2022-06-11  5:52                             ` Ihor Radchenko
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Stallman @ 2022-06-10 22:45 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: schwab, 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. ]]]

It clearly can be useful to compare hash tables for equivalence
of contents.  I see two ways to offer that facility:

* As a new function.  That would be upward-compatible.

* By making `equal' compare them that way.  That would fit the spirit
of `equal', but could break some existing uses of `equal'.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





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

* Re: Comparing hash table objects
  2022-06-10 22:45                           ` Richard Stallman
@ 2022-06-11  5:52                             ` Ihor Radchenko
  2022-06-11 16:04                               ` Stefan Monnier
  0 siblings, 1 reply; 20+ messages in thread
From: Ihor Radchenko @ 2022-06-11  5:52 UTC (permalink / raw)
  To: rms; +Cc: schwab, emacs-devel

Richard Stallman <rms@gnu.org> writes:

> It clearly can be useful to compare hash tables for equivalence
> of contents.  I see two ways to offer that facility:
>
> * As a new function.  That would be upward-compatible.

I have seen various variants of such function in third-party packages
and just in internet search results.
For example, ht-equal? from
https://github.com/Wilfred/ht.el/blob/master/ht.el:

(defun ht-equal? (table1 table2)
  "Return t if TABLE1 and TABLE2 have the same keys and values.
Does not compare equality predicates."
  (declare (side-effect-free t))
  (let ((keys1 (ht-keys table1))
        (keys2 (ht-keys table2))
        (sentinel (make-symbol "ht-sentinel")))
    (and (equal (length keys1) (length keys2))
         (--all?
          (equal (ht-get table1 it)
                 (ht-get table2 it sentinel))
          keys1))))

However, it will not help with the problem of comparing objects
containing hash tables. Unless those obejcts also define special
comparison function (which is inconvenient).

> * By making `equal' compare them that way.  That would fit the spirit
> of `equal', but could break some existing uses of `equal'.

I'd say that using `equal' on hash tables with the actual intention of
comparing tables by `eq' is calling for a trouble. At least, it is
misleading.

Best,
Ihor



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

* Re: Comparing hash table objects
  2022-06-11  5:52                             ` Ihor Radchenko
@ 2022-06-11 16:04                               ` Stefan Monnier
  2022-06-12  9:16                                 ` Ihor Radchenko
  2022-06-12 23:55                                 ` Sam Steingold
  0 siblings, 2 replies; 20+ messages in thread
From: Stefan Monnier @ 2022-06-11 16:04 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: rms, schwab, emacs-devel

> However, it will not help with the problem of comparing objects
> containing hash tables. Unless those obejcts also define special
> comparison function (which is inconvenient).

This is an instance of a fairly general problem with Lisp's equality
tests (and it's not really specific to Lisp, admittedly).

Maybe a half-sane way to solve this problem is to provide a generic
"equality driver" which takes an argument specifying which objects to
compare for structural equality (i.e. where to keep recursing).


        Stefan




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

* Re: Comparing hash table objects
  2022-06-11 16:04                               ` Stefan Monnier
@ 2022-06-12  9:16                                 ` Ihor Radchenko
  2022-06-12 23:55                                 ` Sam Steingold
  1 sibling, 0 replies; 20+ messages in thread
From: Ihor Radchenko @ 2022-06-12  9:16 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: rms, schwab, emacs-devel

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

>> However, it will not help with the problem of comparing objects
>> containing hash tables. Unless those obejcts also define special
>> comparison function (which is inconvenient).
>
> This is an instance of a fairly general problem with Lisp's equality
> tests (and it's not really specific to Lisp, admittedly).
>
> Maybe a half-sane way to solve this problem is to provide a generic
> "equality driver" which takes an argument specifying which objects to
> compare for structural equality (i.e. where to keep recursing).

This might be an option.
It would then help if cl-defstruct supported a default comparator
setting the "equality driver" to be used by default when comparing the
objects using equal.

Best,
Ihor



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

* Re: Comparing hash table objects
  2022-06-11 16:04                               ` Stefan Monnier
  2022-06-12  9:16                                 ` Ihor Radchenko
@ 2022-06-12 23:55                                 ` Sam Steingold
  2022-06-13 13:02                                   ` Stefan Monnier
  1 sibling, 1 reply; 20+ messages in thread
From: Sam Steingold @ 2022-06-12 23:55 UTC (permalink / raw)
  To: emacs-devel, Stefan Monnier

> * Stefan Monnier <zbaavre@veb.hzbagerny.pn> [2022-06-11 12:04:46 -0400]:
>
>> However, it will not help with the problem of comparing objects
>> containing hash tables. Unless those obejcts also define special
>> comparison function (which is inconvenient).
>
> This is an instance of a fairly general problem with Lisp's equality
> tests (and it's not really specific to Lisp, admittedly).

Sadly, this is true.

> Maybe a half-sane way to solve this problem is to provide a generic
> "equality driver" which takes an argument specifying which objects to
> compare for structural equality (i.e. where to keep recursing).

The way Python does it could be a good starting point:
unless a class defines __eq__ method, the comparison is Lisp eq.
So, if a class has structure, it should define the comparison method.
See https://docs.python.org/3/reference/datamodel.html#object.__eq__

-- 
Sam Steingold (http://sds.podval.org/) on Pop 22.04 (jammy) X 11.0.12101003
http://childpsy.net http://calmchildstories.com http://steingoldpsychology.com
https://ij.org/ http://think-israel.org https://fairforall.org
(let ((a "(let ((a %c%s%c)) (format a 34 a 34))")) (format a 34 a 34))



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

* Re: Comparing hash table objects
  2022-06-12 23:55                                 ` Sam Steingold
@ 2022-06-13 13:02                                   ` Stefan Monnier
  2022-06-13 16:18                                     ` Sam Steingold
  0 siblings, 1 reply; 20+ messages in thread
From: Stefan Monnier @ 2022-06-13 13:02 UTC (permalink / raw)
  To: emacs-devel

Sam Steingold [2022-06-12 19:55:08] wrote:
> The way Python does it could be a good starting point:
> unless a class defines __eq__ method, the comparison is Lisp eq.
> So, if a class has structure, it should define the comparison method.
> See https://docs.python.org/3/reference/datamodel.html#object.__eq__

Seems like the exact same way ELisp works.  The problem we have right
now (translated into Python) is that some people now want to add
a `__eq__` method to the class `hash-table` (they argue that the lack of
it was an oversight).  It's easy to do what they ask for, but it breaks
backward compatibility.


        Stefan




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

* Re: Comparing hash table objects
  2022-06-13 13:02                                   ` Stefan Monnier
@ 2022-06-13 16:18                                     ` Sam Steingold
  0 siblings, 0 replies; 20+ messages in thread
From: Sam Steingold @ 2022-06-13 16:18 UTC (permalink / raw)
  To: emacs-devel, Stefan Monnier

> * Stefan Monnier <zbaavre@veb.hzbagerny.pn> [2022-06-13 09:02:41 -0400]:
>
> Sam Steingold [2022-06-12 19:55:08] wrote:
>> The way Python does it could be a good starting point:
>> unless a class defines __eq__ method, the comparison is Lisp eq.
>> So, if a class has structure, it should define the comparison method.
>> See https://docs.python.org/3/reference/datamodel.html#object.__eq__
>
> Seems like the exact same way ELisp works.

including for user-defined classes?!

> The problem we have right now (translated into Python) is that some

please use ELisp terminology too for those who will want to read the sources.

> people now want to add a `__eq__` method to the class `hash-table`
> (they argue that the lack of it was an oversight).

sounds about right.

> It's easy to do what they ask for, but it breaks backward
> compatibility.

I would argue that code relying on `equal' being the same as `eq' for
`hash-table' is a bug.  Exposing such a bug might be painful, but it
should be fixed anyway.

Thank you for your clarifications.

-- 
Sam Steingold (https://youtube.com/channel/UCiW5WB6K4Fx-NhhtZscW7Og) on darwin Ns 10.3.2113
http://childpsy.net http://calmchildstories.com http://steingoldpsychology.com
https://ij.org/ https://ffii.org https://memri.org https://jij.org
He who laughs last thinks slowest.



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

* compat.el and Emacs unstable master branch features (was: bug#63513: [PATCH] Make persist-defvar work with records and hash tables)
       [not found]                                     ` <86d6e412-9e5b-9086-56ce-e3794085096a@daniel-mendler.de>
@ 2023-09-09 12:12                                       ` Ihor Radchenko
  2023-09-09 12:29                                         ` Daniel Mendler
  0 siblings, 1 reply; 20+ messages in thread
From: Ihor Radchenko @ 2023-09-09 12:12 UTC (permalink / raw)
  To: Daniel Mendler
  Cc: Joseph Turner, Stefan Monnier, Adam Porter, Eli Zaretskii,
	phillip.lord, emacs-devel, ~pkal/compat-devel

Daniel Mendler <mail@daniel-mendler.de> writes:

> On 9/9/23 13:35, Ihor Radchenko wrote:
>>> So using Compat here has to wait until compat-30.x is released.
>> 
>> And do I understand correctly that compat-30 will only be released after
>> Emacs 30 is released? If so, it is awkward for :core packages.
>
> compat-30 can be released as soon as Emacs 30 has been reasonably
> stabilized, e.g., when the emacs-30 branch has been frozen, or a bit
> before that. We cannot release much earlier since APIs may still change
> and it is probably undesired to release unfinished APIs to the public
> too early. For reference, I've created the compat-29.1.1 release around
> the day that Eli announced the emacs-29 branch freeze.

I understand the logic, but it does not make things less awkward.

Sometimes, Emacs core packages that are also distributed on ELPA rely on
bugfixes (changed functions) or new functions from master.

It is indeed viable to copy-paste the needed functions into the package
code, but it _feels_ like something compat.el may provide support for.

May it be possible to provide a public API in compat.el to define
compat function versions before they appear in compat.el properly?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>



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

* Re: compat.el and Emacs unstable master branch features (was: bug#63513: [PATCH] Make persist-defvar work with records and hash tables)
  2023-09-09 12:12                                       ` compat.el and Emacs unstable master branch features (was: bug#63513: [PATCH] Make persist-defvar work with records and hash tables) Ihor Radchenko
@ 2023-09-09 12:29                                         ` Daniel Mendler
  2023-09-09 16:52                                           ` Joseph Turner
  2023-09-11  8:45                                           ` Ihor Radchenko
  0 siblings, 2 replies; 20+ messages in thread
From: Daniel Mendler @ 2023-09-09 12:29 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: Joseph Turner, Stefan Monnier, Adam Porter, Eli Zaretskii,
	phillip.lord, emacs-devel, ~pkal/compat-devel

On 9/9/23 14:12, Ihor Radchenko wrote:
> Daniel Mendler <mail@daniel-mendler.de> writes:
>> compat-30 can be released as soon as Emacs 30 has been reasonably
>> stabilized, e.g., when the emacs-30 branch has been frozen, or a bit
>> before that. We cannot release much earlier since APIs may still change
>> and it is probably undesired to release unfinished APIs to the public
>> too early. For reference, I've created the compat-29.1.1 release around
>> the day that Eli announced the emacs-29 branch freeze.
>
> It is indeed viable to copy-paste the needed functions into the package
> code, but it _feels_ like something compat.el may provide support for.
>
> May it be possible to provide a public API in compat.el to define
> compat function versions before they appear in compat.el properly?

I see your point, but I think that Compat provides value for both
external and core packages given its current conservative approach. All
that is needed is to wait for a while after some API has been added and
Compat has been synchronized. Note that we haven't seen many API
additions in Emacs 30 so far. Compare this to compat-29.el which
provides a rich set of new APIs which are all available for external and
core packages depending on older Emacs versions.

I suggest to copy new functions temporarily to the package in question
with an fboundp check, with an additional TODO comment. We can
synchronize with Compat afterwards. Providing a public API won't work
since Compat is not included in Emacs itself. A design criterion of
Compat is also to keep the public API surface as small as possible.

Daniel



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

* Re: compat.el and Emacs unstable master branch features (was: bug#63513: [PATCH] Make persist-defvar work with records and hash tables)
  2023-09-09 12:29                                         ` Daniel Mendler
@ 2023-09-09 16:52                                           ` Joseph Turner
  2023-09-11  8:45                                           ` Ihor Radchenko
  1 sibling, 0 replies; 20+ messages in thread
From: Joseph Turner @ 2023-09-09 16:52 UTC (permalink / raw)
  To: Daniel Mendler
  Cc: Ihor Radchenko, Stefan Monnier, Adam Porter, Eli Zaretskii,
	phillip.lord, emacs-devel, ~pkal/compat-devel


Daniel Mendler <mail@daniel-mendler.de> writes:

> I suggest to copy new functions temporarily to the package in question
> with an fboundp check, with an additional TODO comment. We can
> synchronize with Compat afterwards. Providing a public API won't work
> since Compat is not included in Emacs itself. A design criterion of
> Compat is also to keep the public API surface as small as possible.

fboundp won't work here because copy-tree is available in earlier
versions of Emacs. Since its behavior changed in 30, we could do a
version check + TODO comment?



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

* Re: compat.el and Emacs unstable master branch features (was: bug#63513: [PATCH] Make persist-defvar work with records and hash tables)
  2023-09-09 12:29                                         ` Daniel Mendler
  2023-09-09 16:52                                           ` Joseph Turner
@ 2023-09-11  8:45                                           ` Ihor Radchenko
  2023-09-12 10:02                                             ` compat.el and Emacs unstable master branch features Philip Kaludercic
  1 sibling, 1 reply; 20+ messages in thread
From: Ihor Radchenko @ 2023-09-11  8:45 UTC (permalink / raw)
  To: Daniel Mendler
  Cc: Joseph Turner, Stefan Monnier, Adam Porter, Eli Zaretskii,
	phillip.lord, emacs-devel, ~pkal/compat-devel

Daniel Mendler <mail@daniel-mendler.de> writes:

> ... Providing a public API won't work
> since Compat is not included in Emacs itself. A design criterion of
> Compat is also to keep the public API surface as small as possible.

Maybe it is the time to consider including the compat.el API into Emacs?
We are getting a number of :core packages published on ELPA and
naturally having to solve various compatibility problems.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>



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

* Re: compat.el and Emacs unstable master branch features
  2023-09-11  8:45                                           ` Ihor Radchenko
@ 2023-09-12 10:02                                             ` Philip Kaludercic
  2023-09-12 10:27                                               ` Daniel Mendler
  0 siblings, 1 reply; 20+ messages in thread
From: Philip Kaludercic @ 2023-09-12 10:02 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: Daniel Mendler, Joseph Turner, Stefan Monnier, Adam Porter,
	Eli Zaretskii, phillip.lord, emacs-devel, ~pkal/compat-devel

Ihor Radchenko <yantar92@posteo.net> writes:

> Daniel Mendler <mail@daniel-mendler.de> writes:
>
>> ... Providing a public API won't work
>> since Compat is not included in Emacs itself. A design criterion of
>> Compat is also to keep the public API surface as small as possible.
>
> Maybe it is the time to consider including the compat.el API into Emacs?
> We are getting a number of :core packages published on ELPA and
> naturally having to solve various compatibility problems.

I am a bit behind wrt Compat development.  Are we talking about adding
the `compat-call, etc. macros to the core?  So basically just a

  (defmacro compat-call (&rest args) args)

that would be overriden by compat's compat-call, as soon as that is
loaded



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

* Re: compat.el and Emacs unstable master branch features
  2023-09-12 10:02                                             ` compat.el and Emacs unstable master branch features Philip Kaludercic
@ 2023-09-12 10:27                                               ` Daniel Mendler
  2023-09-13 10:31                                                 ` Philip Kaludercic
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Mendler @ 2023-09-12 10:27 UTC (permalink / raw)
  To: Philip Kaludercic, Ihor Radchenko
  Cc: Joseph Turner, Stefan Monnier, Adam Porter, Eli Zaretskii,
	phillip.lord, emacs-devel, ~pkal/compat-devel

On 9/12/23 12:02, Philip Kaludercic wrote:
> Ihor Radchenko <yantar92@posteo.net> writes:
> 
>> Daniel Mendler <mail@daniel-mendler.de> writes:
>>
>>> ... Providing a public API won't work
>>> since Compat is not included in Emacs itself. A design criterion of
>>> Compat is also to keep the public API surface as small as possible.
>>
>> Maybe it is the time to consider including the compat.el API into Emacs?
>> We are getting a number of :core packages published on ELPA and
>> naturally having to solve various compatibility problems.
> 
> I am a bit behind wrt Compat development.  Are we talking about adding
> the `compat-call, etc. macros to the core?  So basically just a
> 
>   (defmacro compat-call (&rest args) args)
> 
> that would be overriden by compat's compat-call, as soon as that is
> loaded

Yes, if the Emacs maintainers agree I think this could be done. Take
compat.el, remove the part which requires compat-29, and copy it to
lisp/ or lisp/emacs-lisp/. As you said, if Compat (the package) is
installed it will be preferred over the core compat.el. The advantage of
this move is that core package could require compat directly without
passing a noerror argument to require. Furthermore `compat-call' and
`compat-function' would be available and wouldn't have to be copied as
is currently the case for example in erc-compat.el.

Daniel



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

* Re: compat.el and Emacs unstable master branch features
  2023-09-12 10:27                                               ` Daniel Mendler
@ 2023-09-13 10:31                                                 ` Philip Kaludercic
  2023-09-13 17:11                                                   ` Daniel Mendler
  0 siblings, 1 reply; 20+ messages in thread
From: Philip Kaludercic @ 2023-09-13 10:31 UTC (permalink / raw)
  To: Daniel Mendler
  Cc: Ihor Radchenko, Joseph Turner, Stefan Monnier, Adam Porter,
	Eli Zaretskii, phillip.lord, emacs-devel, ~pkal/compat-devel

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

Daniel Mendler <mail@daniel-mendler.de> writes:

> On 9/12/23 12:02, Philip Kaludercic wrote:
>> Ihor Radchenko <yantar92@posteo.net> writes:
>> 
>>> Daniel Mendler <mail@daniel-mendler.de> writes:
>>>
>>>> ... Providing a public API won't work
>>>> since Compat is not included in Emacs itself. A design criterion of
>>>> Compat is also to keep the public API surface as small as possible.
>>>
>>> Maybe it is the time to consider including the compat.el API into Emacs?
>>> We are getting a number of :core packages published on ELPA and
>>> naturally having to solve various compatibility problems.
>> 
>> I am a bit behind wrt Compat development.  Are we talking about adding
>> the `compat-call, etc. macros to the core?  So basically just a
>> 
>>   (defmacro compat-call (&rest args) args)
>> 
>> that would be overriden by compat's compat-call, as soon as that is
>> loaded
>
> Yes, if the Emacs maintainers agree I think this could be done. Take
> compat.el, remove the part which requires compat-29, and copy it to
> lisp/ or lisp/emacs-lisp/. As you said, if Compat (the package) is
> installed it will be preferred over the core compat.el. The advantage of
> this move is that core package could require compat directly without
> passing a noerror argument to require. Furthermore `compat-call' and
> `compat-function' would be available and wouldn't have to be copied as
> is currently the case for example in erc-compat.el.

That sounds good!  How does this look like:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-the-public-API-of-Compat-to-the-core.patch --]
[-- Type: text/x-diff, Size: 3834 bytes --]

From 3245c3c4e6a8a4c35c4072df3a0bfefcabe0555d Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Wed, 13 Sep 2023 12:26:22 +0200
Subject: [PATCH] Add the public API of Compat to the core

* lisp/emacs-lisp/compat.el: Add stub file with minimal definitions,
so that core packages, that haven't been installed from ELPA, can make
use of the public API and use more recent function signatures.
* lisp/progmodes/python.el (compat): Remove 'noerror flag, because
Compat can now be required without the real package being available.
---
 lisp/emacs-lisp/compat.el | 61 +++++++++++++++++++++++++++++++++++++++
 lisp/progmodes/python.el  |  2 +-
 2 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 lisp/emacs-lisp/compat.el

diff --git a/lisp/emacs-lisp/compat.el b/lisp/emacs-lisp/compat.el
new file mode 100644
index 00000000000..4c60093b6be
--- /dev/null
+++ b/lisp/emacs-lisp/compat.el
@@ -0,0 +1,61 @@
+;;; compat.el --- Pseudo-Compatibility for Elisp -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
+
+;; Author:								\
+;;   Philip Kaludercic <philipk@posteo.net>,				\
+;;   Daniel Mendler <mail@daniel-mendler.de>
+;; Maintainer:								\
+;;   Daniel Mendler <mail@daniel-mendler.de>,				\
+;;   Compat Development <~pkal/compat-devel@lists.sr.ht>,
+;;   emacs-devel@gnu.org
+;; URL: https://github.com/emacs-compat/compat
+;; Version: 1.0
+;; Keywords: lisp, maint
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The Compat package on ELPA provides forward-compatibility
+;; definitions for other packages.  While mostly transparent, a
+;; minimal API is necessary whenever core definitions change calling
+;; conventions (e.g. `plist-get' can be invoked with a predicate from
+;; Emacs 29.1 onward).  For core packages on ELPA to be able to take
+;; advantage of this functionality, the macros `compat-function' and
+;; `compat-call' have to be available in the core, usable even if
+;; users do not have the Compat package installed, which this file
+;; ensures.
+
+;; Note that Compat is not a core package and this file is not
+;; available on GNU ELPA.
+
+;;; Code:
+
+(defmacro compat-function (fun)
+  "Return compatibility function symbol for FUN.
+This is a pseudo-compatibility stub for core packages on ELPA,
+that depend on the Compat package, whenever the user doesn't have
+the package installed on their current system."
+  `#',fun)
+
+(defmacro compat-call (fun &rest args)
+  "Call compatibility function or macro FUN with ARGS.
+This is a pseudo-compatibility stub for core packages on ELPA,
+that depend on the Compat package, whenever the user doesn't have
+the package installed on their current system."
+  (cons fun args))
+
+(provide 'compat)
+;;; compat.el ends here
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 4b940b3f13b..bf0e27bc786 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -264,7 +264,7 @@
 (eval-when-compile (require 'subr-x))   ;For `string-empty-p' and `string-join'.
 (require 'treesit)
 (require 'pcase)
-(require 'compat nil 'noerror)
+(require 'compat)
 (require 'project nil 'noerror)
 (require 'seq)
 
-- 
2.39.2


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

* Re: compat.el and Emacs unstable master branch features
  2023-09-13 10:31                                                 ` Philip Kaludercic
@ 2023-09-13 17:11                                                   ` Daniel Mendler
  2023-10-15  8:43                                                     ` Ihor Radchenko
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Mendler @ 2023-09-13 17:11 UTC (permalink / raw)
  To: Philip Kaludercic
  Cc: Ihor Radchenko, Joseph Turner, Stefan Monnier, Adam Porter,
	Eli Zaretskii, phillip.lord, emacs-devel, ~pkal/compat-devel

On 9/13/23 12:31, Philip Kaludercic wrote:
> Daniel Mendler <mail@daniel-mendler.de> writes:
> 
>> On 9/12/23 12:02, Philip Kaludercic wrote:
>>> Ihor Radchenko <yantar92@posteo.net> writes:
>>>
>>>> Daniel Mendler <mail@daniel-mendler.de> writes:
>>>>
>>>>> ... Providing a public API won't work
>>>>> since Compat is not included in Emacs itself. A design criterion of
>>>>> Compat is also to keep the public API surface as small as possible.
>>>>
>>>> Maybe it is the time to consider including the compat.el API into Emacs?
>>>> We are getting a number of :core packages published on ELPA and
>>>> naturally having to solve various compatibility problems.
>>>
>>> I am a bit behind wrt Compat development.  Are we talking about adding
>>> the `compat-call, etc. macros to the core?  So basically just a
>>>
>>>   (defmacro compat-call (&rest args) args)
>>>
>>> that would be overriden by compat's compat-call, as soon as that is
>>> loaded
>>
>> Yes, if the Emacs maintainers agree I think this could be done. Take
>> compat.el, remove the part which requires compat-29, and copy it to
>> lisp/ or lisp/emacs-lisp/. As you said, if Compat (the package) is
>> installed it will be preferred over the core compat.el. The advantage of
>> this move is that core package could require compat directly without
>> passing a noerror argument to require. Furthermore `compat-call' and
>> `compat-function' would be available and wouldn't have to be copied as
>> is currently the case for example in erc-compat.el.
> 
> That sounds good!  How does this look like:

Yes, this is what I meant. I forgot to mention one additional advantage
in my last mail: If the compat.el in core is registered with package.el
as builtin with version 30, the ELPA Compat package wouldn't get pulled
in by external packages which depend on Compat version 29. The core
compat.el version should then be bumped together with the Emacs version.

Daniel



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

* Re: compat.el and Emacs unstable master branch features
  2023-09-13 17:11                                                   ` Daniel Mendler
@ 2023-10-15  8:43                                                     ` Ihor Radchenko
  2023-10-15 12:09                                                       ` Philip Kaludercic
  0 siblings, 1 reply; 20+ messages in thread
From: Ihor Radchenko @ 2023-10-15  8:43 UTC (permalink / raw)
  To: Daniel Mendler
  Cc: Philip Kaludercic, Joseph Turner, Stefan Monnier, Adam Porter,
	Eli Zaretskii, phillip.lord, emacs-devel, ~pkal/compat-devel

Daniel Mendler <mail@daniel-mendler.de> writes:

>>> Yes, if the Emacs maintainers agree I think this could be done. Take
>>> compat.el, remove the part which requires compat-29, and copy it to
>>> lisp/ or lisp/emacs-lisp/. As you said, if Compat (the package) is
>>> installed it will be preferred over the core compat.el. The advantage of
>>> this move is that core package could require compat directly without
>>> passing a noerror argument to require. Furthermore `compat-call' and
>>> `compat-function' would be available and wouldn't have to be copied as
>>> is currently the case for example in erc-compat.el.
>> 
>> That sounds good!  How does this look like:
>
> Yes, this is what I meant. I forgot to mention one additional advantage
> in my last mail: If the compat.el in core is registered with package.el
> as builtin with version 30, the ELPA Compat package wouldn't get pulled
> in by external packages which depend on Compat version 29. The core
> compat.el version should then be bumped together with the Emacs version.

Nobody raised objections. I recommend sending the patch to debbugs (M-x
submit-emacs-patch), so that it can be seen by Emacs maintainers.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>



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

* Re: compat.el and Emacs unstable master branch features
  2023-10-15  8:43                                                     ` Ihor Radchenko
@ 2023-10-15 12:09                                                       ` Philip Kaludercic
  0 siblings, 0 replies; 20+ messages in thread
From: Philip Kaludercic @ 2023-10-15 12:09 UTC (permalink / raw)
  To: Ihor Radchenko
  Cc: Daniel Mendler, Joseph Turner, Stefan Monnier, Adam Porter,
	Eli Zaretskii, phillip.lord, emacs-devel, ~pkal/compat-devel

Ihor Radchenko <yantar92@posteo.net> writes:

> Daniel Mendler <mail@daniel-mendler.de> writes:
>
>>>> Yes, if the Emacs maintainers agree I think this could be done. Take
>>>> compat.el, remove the part which requires compat-29, and copy it to
>>>> lisp/ or lisp/emacs-lisp/. As you said, if Compat (the package) is
>>>> installed it will be preferred over the core compat.el. The advantage of
>>>> this move is that core package could require compat directly without
>>>> passing a noerror argument to require. Furthermore `compat-call' and
>>>> `compat-function' would be available and wouldn't have to be copied as
>>>> is currently the case for example in erc-compat.el.
>>> 
>>> That sounds good!  How does this look like:
>>
>> Yes, this is what I meant. I forgot to mention one additional advantage
>> in my last mail: If the compat.el in core is registered with package.el
>> as builtin with version 30, the ELPA Compat package wouldn't get pulled
>> in by external packages which depend on Compat version 29. The core
>> compat.el version should then be bumped together with the Emacs version.
>
> Nobody raised objections. I recommend sending the patch to debbugs (M-x
> submit-emacs-patch), so that it can be seen by Emacs maintainers.

See bug#66554.

-- 
Philip Kaludercic



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

end of thread, other threads:[~2023-10-15 12:09 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <87wn1axgh6.fsf@breatheoutbreathe.in>
     [not found] ` <83jzx925lv.fsf@gnu.org>
     [not found]   ` <87a5xubwoo.fsf@breatheoutbreathe.in>
     [not found]     ` <87v8csku60.fsf@breatheoutbreathe.in>
     [not found]       ` <83cyyz94c6.fsf@gnu.org>
     [not found]         ` <87a5u2ydzg.fsf@breatheoutbreathe.in>
     [not found]           ` <83msy25g0s.fsf@gnu.org>
     [not found]             ` <624CBB7F-1442-400D-8D4D-1B26EBE9DACB@breatheoutbreathe.in>
     [not found]               ` <jwvr0ndq3b8.fsf-monnier+emacs@gnu.org>
     [not found]                 ` <877cp5bmig.fsf@breatheoutbreathe.in>
     [not found]                   ` <jwvtts8ib4b.fsf-monnier+emacs@gnu.org>
2022-06-08  8:41                     ` Comparing hash table objects Ihor Radchenko
2022-06-08  8:51                       ` Andreas Schwab
2022-06-08  9:17                         ` Ihor Radchenko
2022-06-10 22:45                           ` Richard Stallman
2022-06-11  5:52                             ` Ihor Radchenko
2022-06-11 16:04                               ` Stefan Monnier
2022-06-12  9:16                                 ` Ihor Radchenko
2022-06-12 23:55                                 ` Sam Steingold
2022-06-13 13:02                                   ` Stefan Monnier
2022-06-13 16:18                                     ` Sam Steingold
     [not found]                       ` <8734zoaolv.fsf@localhost>
     [not found]                         ` <jwv1qf8iqua.fsf-monnier+emacs@gnu.org>
     [not found]                           ` <87fs3o8uil.fsf@localhost>
     [not found]                             ` <87msxwa8kd.fsf@breatheoutbreathe.in>
     [not found]                               ` <87il8j7ji9.fsf@localhost>
     [not found]                                 ` <80479897-500e-fe60-6586-0a44ccb5993b@daniel-mendler.de>
     [not found]                                   ` <877coz7f6h.fsf@localhost>
     [not found]                                     ` <86d6e412-9e5b-9086-56ce-e3794085096a@daniel-mendler.de>
2023-09-09 12:12                                       ` compat.el and Emacs unstable master branch features (was: bug#63513: [PATCH] Make persist-defvar work with records and hash tables) Ihor Radchenko
2023-09-09 12:29                                         ` Daniel Mendler
2023-09-09 16:52                                           ` Joseph Turner
2023-09-11  8:45                                           ` Ihor Radchenko
2023-09-12 10:02                                             ` compat.el and Emacs unstable master branch features Philip Kaludercic
2023-09-12 10:27                                               ` Daniel Mendler
2023-09-13 10:31                                                 ` Philip Kaludercic
2023-09-13 17:11                                                   ` Daniel Mendler
2023-10-15  8:43                                                     ` Ihor Radchenko
2023-10-15 12:09                                                       ` Philip Kaludercic

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).