On Mar 4, 2019, at 4:51 AM, Stefan Behnel <stefan_ml@behnel.de> wrote:

I think the main intentions is to close a gap in the language.

   [1,2,3] + [4,5,6]

works for lists and tuples,

   {1,2,3} | {4,5,6}

works for sets, but joining two dicts isn't simply

   {1:2, 3:4} + {5:6}

but requires either some obscure syntax or a statement instead of a simple
expression.

The proposal is to enable the obvious syntax for something that should be
obvious.

I would challenge that this dictionary merging is something that is
obvious.  The existing sequences are simple collections of values
where a dictionary is a mapping of values.  The difference between
the two is akin to the difference between a mathematical array or
set and a unary mapping function.  There is a clear and obvious way to
combine arrays and sets -- concatenation for arrays and union for sets.
Combining mapping functions is less than obvious.

"Putting Metaclasses to Work" (ISBN-13 978-0201433050) presents a more
mathematical view of programming language types that includes two
distinct operations for combining dictionaries -- merge and recursive
merge.

For two input dictionaries D1 & D2 and the output dictionary O

D1 merge D2
    O is D1 with the of those keys of D2 that do not have keys in D1

D1 recursive-merge D2
    For all keys k, O[k] = D1[k] recursive merge D2[k] if both D1[k]
    and D2[k] are dictionaries, otherwise O[k] = (D1 merge D2)[k].

Note that neither of the cases is the same as:

>>> O = D1.copy()
>>> O.update(D2)

So that gives us three different ways to combine dictionaries that are
each sensible.  The following example uses dictionaries from "Putting
Metaclasses to Work":

>>> d1 = {
...     'title': 'Structured Programming',
...     'authors': 'Dahl, Dijkstra, and Hoare',
...     'locations': {
...         'Dahl': 'University of Oslo',
...         'Dijkstra': 'University of Texas',
...         'Hoare': 'Oxford University',
...     },
... }
>>>
>>> d2 = {
...     'publisher': 'Academic Press',
...     'locations': {
...         'North America': 'New York',
...         'Europe': 'London',
...     },
... }
>>>
>>> o = d1.copy()
>>> o.update(d2)
>>> o
{'publisher': 'Academic Press',
 'title': 'Structured Programming',
 'locations': {'North America': 'New York', 'Europe': 'London'},
 'authors': 'Dahl, Dijkstra, and Hoare'}
>>> 
>>> merge(d1, d2)
{'publisher': 'Academic Press',
 'title': 'Structured Programming',
 'locations': {'Dijkstra': 'University of Texas',
               'Hoare': 'Oxford University',
               'Dahl': 'University of Oslo'},
 'authors': 'Dahl, Dijkstra, and Hoare'}
>>>
>>> recursive_merge(d1, d2)
{'publisher': 'Academic Press',
 'title': 'Structured Programming',
 'locations': {'North America': 'New York',
               'Europe': 'London',
               'Dijkstra': 'University of Texas',
               'Hoare': 'Oxford University',
               'Dahl': 'University of Oslo'},
 'authors': 'Dahl, Dijkstra, and Hoare'}
>>>
https://repl.it/@dave_shawley/PuttingMetaclassesToWork

IMO, having more than one obvious outcome means that we should refuse
the temptation to guess.  If we do, then the result is only obvious
to a subset of users and will be a surprise to the others.

It's also useful to note that I am having trouble coming up with
another programming language that supports a "+" operator for map types.

Does anyone have an example of another programming language that
allows for addition of dictionaries/mappings?

If so, what is the behavior there?

- dave
--
Any linter or project that treats PEP 8 as mandatory has *already*
failed, as PEP 8 itself states that the rules can be broken as needed. - Paul Moore.