bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#49848: 27.2.50; map-merge plist return alist


From: Basil L. Contovounesios
Subject: bug#49848: 27.2.50; map-merge plist return alist
Date: Wed, 04 Aug 2021 01:41:35 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

tags 49848 + patch
quit

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Rajeev N via "Bug reports for GNU Emacs, the Swiss army knife of text
> editors" <bug-gnu-emacs@gnu.org> writes:
>
>> (map-merge 'plist nil '(:a 1))
>> expected: '(:a 1)
>> got: '((:a . 1))
>
> I can reproduce this behavior and consider it a bug.
>
> The implementation of `map-merge' starts with an empty plist "RESULT"
> (i.e., nil) and fills it like
>
>       (map-do (lambda (key value)
>                 (setf (map-elt result key) value))
>               (pop maps))
>
> The setter of `map-elt' treats nil as empty alist (at the end, this is
> decided by `map--plist-p' which doesn't consider nil a plist).
>
> So the underlying problem is more general, maybe this is not the only
> issue this ambiguity causes.

There's not much we can do about the inherent ambiguity between empty
alists and plists, short of introducing other functions alongside
map-elt/map-put! that take an explicit type.  But then the justification
for using map.el functions is kind of lost.

In the specific case of merging maps into a desired type, we can simply
be more careful in such ambiguous cases.  The attached patch does that,
while also avoiding the quadratic lookup behaviour for lists.

While there, I noticed more discrepancies, however.  map-merge-with
promises to call its function argument whenever multiple keys are eql,
but that does not always correspond with map-merge, i.e. sometimes
non-eql keys are merged:

(progn
  (require 'map)
  (map-merge-with 'list (lambda (a b) (message ">>> %s %s" a b) b)
                  `((,(string ?a) . 1))
                  `((,(string ?a) . 2))))

In Emacs 26, it returns (("a" . 2) ("a" . 1)) without printing.
In Emacs 27 and 28, it returns (("a" . 2)) without printing.

Do we consider this a regression in Emacs 27 and try to fix it in 28
(keeping in mind that map.el is also a GNU ELPA package)?

Or do we drop the eql guarantee in the docstring, and call the function
argument whenever two keys are merged, as in the attached patch?

I think the latter option may facilitate the equal-ity consistency
being discussed in https://bug.gnu.org/47368.

WDYT?

Thanks,

-- 
Basil

Attachment: 0001-Fix-merging-of-ambiguous-nil-maps.patch
Description: Text Data


reply via email to

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