<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 If we use this "literally concat" metaphor, I still think set should have `+` as alias to `|` for consistency.<span class="gmail-im"><br></span></blockquote><div><br></div><div>I agree.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>

I think "|" keeps commutativity only because it's minor than `+`.

</div></blockquote><div><br></div><div>I suppose that's true, fair point.</div><div><br></div><div>I guess I would be ok with | no longer always implying commutativity if we were repurposing it for some radically different purpose. But dicts and sets are similar enough that I think having them both use similar but ultimately different definitions of "|" is going to have non-zero cost, especially when reading or modifying future code that makes heavy use of both data structures.</div><div><br></div><div>Maybe that cost is worth it. I'm personally not convinced, but I do think it should be taken into account..<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
Hmm.  The PEP proposed dict - dict, which is similar to set - set (difference).

</div></blockquote><div><br></div><div>Now that you point it out, I think I also dislike `d1 - d2` for the same reasons I listed earlier: it's not consistent with set semantics. One other objection I overlooked is that the PEP currently requires both operands to be dicts when doing "d1 - d2" . So doing {"a": 1, "b": 2, "c": 3} - ["a", "b"] is currently disallowed (though doing d1 -= ["a", "b"] is apparently ok).</div><div><br></div><div>I can sympathize: allowing "d1 - some_iter" feels a little too magical to me. But it's unfortunately restrictive -- I suspect removing keys stored within a list or something would be just as common of a use-case if not more so then removing keys stored in another dict.</div><div><br></div><div>I propose that we instead add methods like "d1.without_keys(...)" and "d1.remove_keys(...)" that can accept any iterable of keys. These two methods would replace "d1.__sub__(...)" and "d1.__isub__(...)" respectively. The exact method names and semantics could probably do with a little more bikeshedding, but I think this idea would 
remove a false symmetry between "d1 + d2" and "d1 - d2" that doesn't actually really exist while being more broadly useful.</div><div><br></div><div>Or I guess we could just remove that restriction: "it feels too magical" isn't a great objection on my part. Either way, that part of the PEP could use some more refinement, I think.<br></div><div><br></div><div>-- Michael<br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div> <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Mar 6, 2019 at 8:29 AM Inada Naoki <<a href="mailto:songofacandy@gmail.com">songofacandy@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Mar 6, 2019 at 10:59 PM Michael Lee <<a href="mailto:michael.lee.0x2a@gmail.com" target="_blank">michael.lee.0x2a@gmail.com</a>> wrote:<br>
<br>
><br>
> I think the behavior proposed in the PEP makes sense whether you think of "+" as meaning "concatenation" or "merging".<br>
><br>
> If your instinct is to assume "+" means "concatenation", then it would be natural to assume that {"a": 1, "b": 2} + {"c": 3, "b": 4} would be identical to {"a": 1, "b": 2, "c": 3, "b": 4} -- literally concat the key-value pairs into a new dict.<br>
><br>
<br>
Nice explanation.  You reduced my opposite to `+` by "literally concat".<br>
Better example, {"a": 1, "b": 2} + {"c": 4, "b": 3} == {"a": 1, "b":<br>
2, "c": 4, "b": 3} == {"a": 1, "b": 3, "c": 4}<br>
<br>
On the other hand, union of set is also "literally concat".  If we use<br>
this "literally concat" metaphor,<br>
I still think set should have `+` as alias to `|` for consistency.<br>
<br>
><br>
> Using "|" would also violate an important existing property of unions: the invariant "d1 | d2 == d2 | d1" is no longer true. As far as I'm aware, the union operation is always taken to be commutative in math, and so I think it's important that we preserve that property in Python. At the very least, I think it's far more important to preserve commutativity of unions then it is to preserve some of the invariants I've seen proposed above, like "len(d1 + d2) == len(d1) + len(d2)".<br>
><br>
<br>
I think both rule are "rather a coincidence than a conscious decision".<br>
<br>
I think "|" keeps commutativity only because it's minor than `+`.  Easy operator<br>
is abused easily more than minor operator.<br>
<br>
And I think every "coincidence" rules are important.  They makes<br>
understanding Python easy.<br>
Every people "discover" rules and consistency while learning language.<br>
<br>
This is a matter of balance.  There are no right answer.  Someone<br>
*feel* rule A is important than B.<br>
Someone feel opposite.<br>
<br>
<br>
> But I do know that I'm a strong -1 on adding set operations to dicts: it's not possible to preserve the existing semantics of union (and intersection) with dict and  think expressions like "d1 | d2" and "d1 & d2" would just be confusing and misleading to encounter in the wild.<br>
<br>
Hmm.  The PEP proposed dict - dict, which is similar to set - set (difference).<br>
To me, {"a": 1, "b": 2} - {"b": 3} = {"a": 1} is confusing than {"a":<br>
1, "b": 2} - {"b"} = {"a": 1}.<br>
<br>
So I think borrow some semantics from set is good idea.<br>
Both of `dict - set` and `dict & set` makes sense to me.<br>
<br>
* `dict - set` can be used to remove private keys by "blacklist".<br>
* `dict & set` can be used to choose public keys by "whiltelist".<br>
<br>
-- <br>
Inada Naoki  <<a href="mailto:songofacandy@gmail.com" target="_blank">songofacandy@gmail.com</a>><br>
</blockquote></div>