GNU bug report logs -
#49848
27.2.50; map-merge plist return alist
Previous Next
Reported by: Rajeev N <rajeev.jnk <at> sivalik.com>
Date: Tue, 3 Aug 2021 19:40:02 UTC
Severity: normal
Tags: patch
Found in version 27.2.50
Fixed in version 28.1
Done: "Basil L. Contovounesios" <contovob <at> tcd.ie>
Bug is archived. No further changes may be made.
Full log
Message #22 received at control <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
tags 49848 + patch
quit
Michael Heerdegen <michael_heerdegen <at> web.de> writes:
> Rajeev N via "Bug reports for GNU Emacs, the Swiss army knife of text
> editors" <bug-gnu-emacs <at> 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
[0001-Fix-merging-of-ambiguous-nil-maps.patch (text/x-diff, attachment)]
This bug report was last modified 3 years and 282 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.