tags 49848 + patch quit Michael Heerdegen writes: > Rajeev N via "Bug reports for GNU Emacs, the Swiss army knife of text > editors" 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