Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Christopher Barker
Oops, meant for the list:

> >>
> >> > Chris seems to accept that sometimes you can use a dict subclass, and
> >> > that my proposal will give some representation of "practical
> >> > experience".
> >>
> >> I said "definitely won't", not "will give some". So, no.
> >
> >
> > Jonathan: Chris A. is right. But if you think an example implementation
> is useful, go ahead and make one — it’s actually quite easy, and I’m pretty
> sure code has already been posted here as well.
>
> --
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Steven D'Aprano
On Fri, Mar 22, 2019 at 07:59:03AM +, Jonathan Fine wrote:
> Steven D'Aprano wrote:
> 
> > (For the record, the PEP isn't set in stone in regards to the choice of
> > operator.
> 
> Steven: Please say what parts of the PEP you consider to be set in
> stone. This will allow discussion to focus on essentials rather than
> details.

The PEP is primarily about making a merge operator, so that stays, 
regardless of whether it's spelled + | or something else. Otherwise 
there's no point to the PEP.

If there is demand for a merged() method/function, that go into a 
competing PEP, but it won't be part of this PEP.

If anyone wants to propose syntax for chained method calls (fluent 
programming) so we can write d.copy().update(), that won't be in this 
PEP either. Likewise for new syntax to turn method calls into operators. 
Feel free to propose a competing PEP (and I might even support yours, if 
it makes a good enough case).

A grey area is the "last wins" merge behaviour matching update(). In 
theory, if somebody made an absolutely brilliant case for some other 
behaviour, I could change my mind, but it would have to be pretty 
amazing. In the absence of such, I'm going to use my perogative as PEP 
author to choose the behaviour I prefer to see, and leave alternatives 
to subclasses.


-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Jonathan Fine
Python fits well in the mind, because (1) by design it reduces
cognitive load, and (2) it encourages its users to reduce cognitive
load, and (3) we have a culture of reading code, taking pride in our
code. Readability counts.
https://en.wikipedia.org/wiki/Cognitive_load

Steven D'Aprano says that examples such as below don't help us discuss
the cognitive load associated with dict + dict.

> 1. Toy examples using generic names don't count.
> eggs += spam

I assume he's referring to my example
>>> items.update(points)
>>> items += points
In this example, items.update gives useful additional information.

We expect, from duck typing and sensible naming, that points can be
iterated to give key value pairs. In Python, when
>>> a + b
gives one of
TypeError: unsupported operand type(s) for +: 'int' and 'str'
TypeError: Can't convert 'int' object to str implicitly
we get a very strong hint to write instead something like
a + int(b)
str(a) + b
so that the nature of the addition is made clear to the next person
who reads the code (who might be ourselve, in a crisis, in ten years
time.)

(JavaScript does implicit conversion. This makes the code easier to
write, harder to read, and harder to maintain.)

For certain values of dct and lst we get
>>> lst += dct
>>> lst
[('a', 1), ('b', 2), 'c', 'd']

For the same values of dct and lst (if proposal allowed)
>>> dct += lst
>>> dct
{'a': 1, 'b': 2, 'c': 3, 'd': 4}

In these examples, dct is a dict, and lst is a list. This behaviour is
something Python users will have to learn, and have in their mind,
whenever they see '+=' in unfamiliar code.

I find this as much an unwelcome cognitive load as that produced by Javascript's
> 2 * "8"
16
> 2 + "8"
"28"

To be fair, this may in part be a problem with our expectations about +=.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Jonathan Fine
Steven D'Aprano wrote:

> (For the record, the PEP isn't set in stone in regards to the choice of
> operator.

Steven: Please say what parts of the PEP you consider to be set in
stone. This will allow discussion to focus on essentials rather than
details.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Chris Angelico
On Fri, Mar 22, 2019 at 6:47 PM Jonathan Fine  wrote:
>
> Chris Angelico wrote:
>
> > The trouble with that is that you can't always use a dict subclass (or
> > a non-subclass MutableMapping implementation, etc, etc, etc). There
> > are MANY situations in which Python will give you an actual real dict,
> > and it defeats the purpose if you then have to construct an
> > AddableDict out of it just so you can add something to it. Not every
> > proposed change makes sense on PyPI, and it definitely won't get a
> > fair representation in "practical experience".
>
> Chris seems to accept that sometimes you can use a dict subclass, and
> that my proposal will give some representation of "practical
> experience".

I said "definitely won't", not "will give some". So, no.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Chris Angelico
On Fri, Mar 22, 2019 at 1:58 PM David Mertz  wrote:
>
> On Thu, Mar 21, 2019, 10:15 PM Steven D'Aprano  wrote:
>> > Of course I could learn it and teach it, but it will always feel
>> > like a wart in the language.
>>
>> Would that wartness be lessoned if it were spelled | or << instead?
>
> Yes, definitely. Both those spellings feel pretty natural to me. They don't 
> have the misleading associations '+' carries. I'm kinda fond of '<<' because 
> it visitation resembles an arrow that I can think of as "put the stuff here 
> into there".
>

Please no. The "cuteness" value of abusing the operator to indicate
information flow got old shortly after C++ did it, and it doesn't
help. With normal operator overloading, you can say "the + operator
means addition", and then define "addition" for different types.

Perhaps that ship has sailed, since we already have division between
path objects, but at least in that example it is VERY closely related.
There's no use of "<<" inside string literals with dictionaries the
way there's "/foo/bar/spam" in paths.

Dictionary merging is a form of addition. It's also related to set
union, which is well known as part of the pipe operator. Either of
those is far better than abusing left shift.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-22 Thread Jonathan Fine
Chris Angelico wrote:

> The trouble with that is that you can't always use a dict subclass (or
> a non-subclass MutableMapping implementation, etc, etc, etc). There
> are MANY situations in which Python will give you an actual real dict,
> and it defeats the purpose if you then have to construct an
> AddableDict out of it just so you can add something to it. Not every
> proposed change makes sense on PyPI, and it definitely won't get a
> fair representation in "practical experience".

Chris seems to accept that sometimes you can use a dict subclass, and
that my proposal will give some representation of "practical
experience".

Even if not perfect, such benefits are I think worth having. And Chris
gives no evidence (or examples) beyond his own assertions, that my
proposal would not produce a fair representation of practical
experience.

Why don't we just try it and see. This would engage us with the users.
And it would, as I suggested, clarify and document the syntax and
semantics. And provide backporting to current versions of Python.

By the way, in "Masterminds of Programming" [page 20], Guido gives
four lines of defence against the unwise addition of a "favorite
feature" to the language. They are

[1] Explain to people that they can already do what they want.
[2] Tell them to write their own module or class to encapsulate the feature.
[3] Accept the feature, as pure Python, in the standard library.
[4] Accept the feature as a C-Python extension standard.

And [4] is, in Guido's words
>   the last line of defense before we have to admit [...]
>   this is so useful [...] so we'll have to change the language

I think the pure Python implementation is important. If the supporters
of this proposal are not willing to provide this, then I will (along
with anyone else who volunteers).

http://shop.oreilly.com/product/9780596515171.do # Masterminds of Programming

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread MRAB

On 2019-03-22 02:40, Dan Sommers wrote:

On 3/21/19 9:19 PM, Christopher Barker wrote:


https://docs.python.org/3.8/library/collections.html has some
examples using collections.Counter, which is clearly described
as being a subclass of dict.  Amongst the examples:

 c + d  # add two counters together:  c[x] + d[x]

That's the + operator operating on two dicts (don't make me
quote the Liskov Substitution Principle), but doing something
really different than the base operator.

So if I know that c and d (or worse, that one of them) is a
dict, then interpreting c + d becomes much more interesting,



Killing a use of a common operator with a very common built in data type
because the operator is used in a different way by a specialized object in
the stdlib seems a bit backwards to me.


Perhaps.  Note that Counter also uses | and & for other
operations that probably wouldn't make much sense on base
dicts.


Frankly, I think considering Counter as a dict subclass is the mistake
here, even if it is true.


I had the same thought that Counter is misdesigned in one
way or another, but (a) that ship has long sailed, and (b)
I didn't want to run off on that tangent.


[snip]
Counter is trying to provide the functionality of 2 kinds of container:

1. A counting container.

2. A multi-set.

+ makes sense for counting (sum); | makes sense for multi-sets (union).
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread David Mertz
On Thu, Mar 21, 2019, 10:15 PM Steven D'Aprano  wrote:

> What would be the most useful behaviour for dict "addition" in your
> opinion?
>

Probably what I would use most often was a "lossless" merging in which
duplicate keys resulted in the corresponding value becoming a set
containing all the merged values. E.g.

>>> d1 = {1: 55, 2: 77, 3: 88}
>>> d2 = {3: 99, 4: 22}
>>> add(d1, d2)
{1: 55, 2: 77, 3: {88, 99}, 4:22}

I'm sure most users would hate this too. It changes the type of values
between a thing and a set of things, and that has to be sorted out
downstream. But it is lossless in a similar way to Counter or sequence
addition.

I can write what I want perfectly well. Perhaps useing defaultdict as a
shortcut to get there. And I know there are some behaviors I have not
specified here, but my function can do whatever I want in the edge cases.

If we're to see 'd1 + d2' for the first time without having followed this
discussion, my guess would be behavior similar to what I show.


> Of course I could learn it and teach it, but it will always feel
> > like a wart in the language.
>
> Would that wartness be lessoned if it were spelled | or << instead?
>

Yes, definitely. Both those spellings feel pretty natural to me. They don't
have the misleading associations '+' carries. I'm kinda fond of '<<'
because it visitation resembles an arrow that I can think of as "put the
stuff here into there".

> In contrast, once you tell me about the special object "vectorised
> arrays",
> > `arr1 + arr2` does exactly what is expect in NumPy.
>
> I don't know Numpy well enough to know whether that is elementwise
> addition or concatenation or something else, so that example doesn't
> resonate with me. I can't guess what you expect, and I have no confidence
> that my guess (matrix addition of equal-sized arrays, an exception if
> unequal) will be what Numpy does
>

Fair enough. I've worked with NumPy long enough that perhaps I forget what
my first intuition was. I accept that it's non-obvious to many users.

FWIW, I really love NumPy behavior, but it's a shift in thinking vs lists.
E.g.

>>> a = array([1, 2, 3])
>>> b = array([[10, 11, 12], [100, 200, 300]])
>>> a + b
[[  11   13   15 ]
 [ 101 202 303]]

This is "broadcasting" of compatible shapes.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Dan Sommers

On 3/21/19 9:19 PM, Christopher Barker wrote:


https://docs.python.org/3.8/library/collections.html has some
examples using collections.Counter, which is clearly described
as being a subclass of dict.  Amongst the examples:

 c + d  # add two counters together:  c[x] + d[x]

That's the + operator operating on two dicts (don't make me
quote the Liskov Substitution Principle), but doing something
really different than the base operator.

So if I know that c and d (or worse, that one of them) is a
dict, then interpreting c + d becomes much more interesting,



Killing a use of a common operator with a very common built in data type
because the operator is used in a different way by a specialized object in
the stdlib seems a bit backwards to me.


Perhaps.  Note that Counter also uses | and & for other
operations that probably wouldn't make much sense on base
dicts.


Frankly, I think considering Counter as a dict subclass is the mistake
here, even if it is true.


I had the same thought that Counter is misdesigned in one
way or another, but (a) that ship has long sailed, and (b)
I didn't want to run off on that tangent.

My point remains:  because Counter is a subclass of dict,
and Counter uses the + operator for something that doesn't
apply to base dicts, adding + to dicts *may* cause
confusion that wasn't there before.

Presently, +, -, |, and & all raise an exception when given
a Counter and a dict.  This (raising an exception) is
probably still the Right Thing to do in that case, even with
a + operator on dicts, but that violates the LSP and IMO the
PLS.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Christopher Barker
>
> https://docs.python.org/3.8/library/collections.html has some
> examples using collections.Counter, which is clearly described
> as being a subclass of dict.  Amongst the examples:
>
>  c + d  # add two counters together:  c[x] + d[x]
>
> That's the + operator operating on two dicts (don't make me
> quote the Liskov Substitution Principle), but doing something
> really different than the base operator.
>
> So if I know that c and d (or worse, that one of them) is a
> dict, then interpreting c + d becomes much more interesting,


Killing a use of a common operator with a very common built in data type
because the operator is used in a different way by a specialized object in
the stdlib seems a bit backwards to me.

Frankly, I think considering Counter as a dict subclass is the mistake
here, even if it is true.

-CHB
-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Steven D'Aprano
On Thu, Mar 21, 2019 at 08:13:01PM -0400, David Mertz wrote:

> On Thu, Mar 21, 2019, 7:48 PM Steven D'Aprano  wrote:
[...]
> Nonetheless, if I see `dict1 + dict2` the meaning you intend in the PEP
> does not jump out as the obvious behavior. Nor even as the most useful
> behavior. 

What would be the most useful behaviour for dict "addition" in your 
opinion?


> Of course I could learn it and teach it, but it will always feel
> like a wart in the language.

Would that wartness be lessoned if it were spelled | or << instead?

 
> In contrast, once you tell me about the special object "vectorised arrays",
> `arr1 + arr2` does exactly what is expect in NumPy.

I don't know Numpy well enough to know whether that is elementwise 
addition or concatenation or something else, so that example doesn't 
resonate with me. I can't guess what you expect, and I have no 
confidence that my guess (matrix addition of equal-sized arrays, an 
exception if unequal) will be what Numpy does.


> > And your subjective feeling is well-noted :-)
> 
> This is more than "merely subjective."

If it is more than subjective, then there must be an objective test that 
anyone, or a computer program, could do to tell whether or not the + 
operator on dicts will be ... um, what? A wart? Ugly? Both of those are 
subjective value judgements, so I'm not sure what objective claim you 
believe you are making which is "more than" subjective.

The point is, I'm not *discounting* the subjective claims that + on 
dicts is ugly. I've acknowledged them, and the next draft of the PEP 
will do so too. But repetition doesn't make a subjective value judgement 
objective.

It might boil down to a subjective preference for + over | or visa 
versa, or another operator, or no operator at all. That's fine: language 
design is partly subjective. But I'd like to see more comments based on 
objective reasons we can agree on, and fewer arguments that boil down to 
"I just don't like it".



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Dan Sommers

On 3/21/19 6:46 PM, Steven D'Aprano wrote:


Antoine and Serhiy seem to worry that there are existing uses of + which
are currently easy to understand but will become less so if dict.__add__
is added. I respect that worry, even if I doubt that they are correct.

If someone can demonstrate that their fear is well-founded, that would
be an excellent counter-argument to the PEP's proposal to use +.


https://docs.python.org/3.8/library/collections.html has some
examples using collections.Counter, which is clearly described
as being a subclass of dict.  Amongst the examples:

c + d  # add two counters together:  c[x] + d[x]

That's the + operator operating on two dicts (don't make me
quote the Liskov Substitution Principle), but doing something
really different than the base operator.

So if I know that c and d (or worse, that one of them) is a
dict, then interpreting c + d becomes much more interesting,
but arguably no worse than c.update(d).  Yes, it's "just"
polymorphism, but IMO it violates the Principle of Least
Surprise.

My apologies if this is covered elsewhere in this thread, or
it doesn't meet the bar Steven set.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread David Mertz
On Thu, Mar 21, 2019, 7:48 PM Steven D'Aprano  wrote:

> A number of people including Antoine and Serhiy seem to have taken the
> position that merely adding dict.__add__ will make existing code using +
> harder to understand, as you will need to consider not just numeric
> addition and concatenation, but also merging, when reading code.
>
> Would you agree that this example of + is perfectly clear today?
>
> for digit in digits:
> num = num*10 + digit
>
> By both the naming (digit, num) and presence of multiplication by the
> literal 10, it should be pretty obvious that this is probably doing
> integer addition.
>

Yep. This is clear and will not become less clear if some more objects grow
an .__add__() methods. Already, it is POSSIBLE that `num` and `digit` mean
something other than numbers. Bad naming of variables if so, but not
prohibited.

For example, NumPy uses '+' and '*' for elementwise operations, often with
broadcasting to different areas shapes. Maybe that's code dealing with
vectorised arrays... But probably not.

Holoviews users '+' and '*' to combine elements of graphs. E.g

labelled = low_freq * high_freq * linpoints
overlay + labelled + labelled.Sinusoid.Low_Frequency

ggplot in R has similar behavior. Maybe your loop is composing a complex
graph... But probably not.

Nonetheless, if I see `dict1 + dict2` the meaning you intend in the PEP
does not jump out as the obvious behavior. Nor even as the most useful
behavior. Of course I could learn it and teach it, but it will always feel
like a wart in the language.

In contrast, once you tell me about the special object "vectorised arrays",
`arr1 + arr2` does exactly what is expect in NumPy.

And your subjective feeling is well-noted :-)
>

This is more than "merely subjective." I teach Python. I write books about
Python. I've had tens of millions of readers of articles I've written about
Python. I'm not the only person in this discussion with knowledge of
learners and programmers and scientists... But the opinions I'm expressing
ARE on their behalf too (as I perceive likely surprise and likely bugs).

I like most of the design of Python. Almost all, even. But there are a few
warts in it. This would be a wart.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Steven D'Aprano
On Thu, Mar 21, 2019 at 03:10:48PM -0700, Brandt Bucher wrote:
> For anyone interested in "trying it out": if you're not against cloning and
> compiling CPython yourself, here is a PEP 584 C implementation I have PR'd
> against master right now. I'm keeping it in sync with the draft PEP as it
> changes, so subtraction performance is not overly optimized yet, but it
> will show you the *exact* behavior outlined in the PEP on the dict builtin
> and its subclasses. The relevant branch is called "addiction". You can
> clone it from:

That's great, thank you!

For the sake of comparisons, could you support | as an alias? That will 
allow people to get a feel for whether a+b or a|b looks nicer.


(For the record, the PEP isn't set in stone in regards to the choice of 
operator.

> https://github.com/brandtbucher/cpython.git



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Steven D'Aprano
On Thu, Mar 21, 2019 at 06:02:05PM -0400, David Mertz wrote:
> I dislike the symbol '+' to mean "dictionary merging with value updates." I
> have no objection to, and mildly support, adding '|' with this meaning.
> 
> It's not really possible to give "that one example" where + for meeting
> makes code less clear... In my eyes it would be EVERY such use. 

I suspect that I may not have explained myself properly. Sorry. Let me 
try to explain again.

A number of people including Antoine and Serhiy seem to have taken the 
position that merely adding dict.__add__ will make existing code using + 
harder to understand, as you will need to consider not just numeric 
addition and concatenation, but also merging, when reading code.

*If this were true* it would be an excellent argument against using + 
for dict merges. But is it true?

Would you agree that this example of + is perfectly clear today?

for digit in digits:
num = num*10 + digit

By both the naming (digit, num) and presence of multiplication by the 
literal 10, it should be pretty obvious that this is probably doing 
integer addition.

(I suppose it is conceivable that this is doing sequence repetition and 
concatenation, but given the names that interpretation would be rather 
unexpected.)

We shouldn't find it hard to understand that code, using nothing more 
than *local* context. There's no need to search the global context to 
find out what num and digits are.

(Although in the specific example I copied that snippet from, that 
information is only two or three lines away. But in principle, we might 
have needed to search an arbitrarily large code base to determine what 
they were.)

Adding dict.__add__ isn't going to make that example harder to 
understand. If it did, that would be a big blow to the + proposal.

Antoine and Serhiy seem to worry that there are existing uses of + which 
are currently easy to understand but will become less so if dict.__add__ 
is added. I respect that worry, even if I doubt that they are correct.

If someone can demonstrate that their fear is well-founded, that would 
be an excellent counter-argument to the PEP's proposal to use +.

What *doesn't* count as a demonstration:

1. Toy examples using generic names don't count. With generic, 
meaningless names, they're not meaningful now and so adding dict.__add__ 
won't make them *less* meaningful:


# is this concatenation or numeric addition? who can tell?
for spam in spammy_macspamface:
eggs += spam


Regardless of whether dicts support + or not, we would still have to 
search the global context to work out what eggs and spam are. 
Adding dict.__add__ doesn't make this harder.


2. Purely opinion-based subjective statements, since they basically boil 
down to "I don't like the use of + for dict merging." That point has 
been made, no need to keep beating that drum.


3. Arguments based on unfamiliarity to the new operator:

preferences += {'EDITOR': 'ed', 'PAGESIZE': 'A4'}

might give you a bit of a double-take the first time you see it, but it 
surely won't still be surprising you in five years time.


I realise that this is a high bar to reach, but if somebody does reach 
it, and demonstrates that Antoine and Serhiy's fears are well-founded, 
that would be a very effective and convincing argument.


> Every
> example presented in this thread or in the PEP feels wrong to me. I know
> about operator overloading and dunder methods and custom classes. My
> intuition about '+' from math, other programming languages, and Python,
> simply does not lead me to expect the proposed meaning.

And your subjective feeling is well-noted :-)


-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Chris Angelico
On Fri, Mar 22, 2019 at 3:42 AM Steven D'Aprano  wrote:
> And to those who support this PEP, code examples where a dict merge
> operator will help are most welcome!

Since Python examples don't really exist yet, I'm reaching for another
language that DOES have this feature. Pike's mappings (broadly
equivalent to Python's dicts) can be added (actually, both + and | are
supported), with semantics equivalent to PEP 584's. Translated into
Python syntax, here's a section from the implementation of
Process.run():

def run(cmd, modifiers={}):
...
...
p = Process(cmd, modifiers + {
"stdout": mystdout->pipe(),
"stderr": mystderr->pipe(),
"stdin": mystdin->pipe(),
})

In Val.TimeTZ, a subclass that adds a timezone attribute overrides a
mapping-returning method to incorporate the timezone in the result
mapping. Again, translated into Python syntax:

def tm(self):
return super().tm() + {"timezone": self.timezone}

To spawn a subprocess with a changed environment variable:

//from the Process.create_process example
Process.create_process(({ "/usr/bin/env" }),
(["env" : getenv() + (["TERM":"vt100"]) ]));

# equivalent Python code
subprocess.Popen("/usr/bin/env",
env=os.environ + {"TERM": "vt100"})

All of these examples could be done with the double-star syntax, as
they all use simple literals. But addition looks a lot cleaner IMO,
and even more so if you're combining multiple variables rather than
using literals.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread David Mertz
I dislike the symbol '+' to mean "dictionary merging with value updates." I
have no objection to, and mildly support, adding '|' with this meaning.

It's not really possible to give "that one example" where + for meeting
makes code less clear... In my eyes it would be EVERY such use. Every
example presented in this thread or in the PEP feels wrong to me. I know
about operator overloading and dunder methods and custom classes. My
intuition about '+' from math, other programming languages, and Python,
simply does not lead me to expect the proposed meaning.

On Thu, Mar 21, 2019, 12:43 PM Steven D'Aprano  wrote:

> I'd like to make a plea to people:
>
> I get it, there is now significant opposition to using the + symbol for
> this proposed operator. At the time I wrote the first draft of the PEP,
> there was virtually no opposition to it, and the | operator had very
> little support. This has clearly changed.
>
> At this point I don't think it is productive to keep making subjective
> claims that + will be more confusing or surprising. You've made your
> point that you don't like it, and the next draft^1 of the PEP will make
> that clear.
>
> But if you have *concrete examples* of code that currently is easy to
> understand, but will be harder to understand if we add dict.__add__,
> then please do show me!
>
> For those who oppose the + operator, it will help me if you made it
> clear whether it is *just* the + symbol you dislike, and would accept
> the | operator instead, or whether you hate the whole operator concept
> regardless of how it is spelled.
>
> And to those who support this PEP, code examples where a dict merge
> operator will help are most welcome!
>
>
>
>
> ^1 Coming Real Soon Now™.
>
>
> --
> Steven
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Chris Angelico
On Fri, Mar 22, 2019 at 8:44 AM Jonathan Fine  wrote:
>
> Antoine Pitrou wrote:
> > Note that, if you're able to live with a third-party dependency, the
> > `toolz` package has what you need (and lots of other things too):
> > https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.merge
>
> I suggest that the supporters of dict + dict make (and put up on PyPi)
> a pure-Python subclass of dict that has the desired properties. This
> would
>
> 1. Clarify and document the syntax and semantics.
> 2. Help with exploration and testing.
> 3. Provide a 'back-port' mechanism to current Python.
> 4. Give the proposal the benefit of practical experience.
>

The trouble with that is that you can't always use a dict subclass (or
a non-subclass MutableMapping implementation, etc, etc, etc). There
are MANY situations in which Python will give you an actual real dict,
and it defeats the purpose if you then have to construct an
AddableDict out of it just so you can add something to it. Not every
proposed change makes sense on PyPI, and it definitely won't get a
fair representation in "practical experience".

If someone's proposing adding a new module to the standard library,
then by all means, propose PyPI. But changes to core types can't be
imported from other modules. Python is not Ruby.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Jonathan Fine
Antoine Pitrou wrote:
> Note that, if you're able to live with a third-party dependency, the
> `toolz` package has what you need (and lots of other things too):
> https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.merge

I suggest that the supporters of dict + dict make (and put up on PyPi)
a pure-Python subclass of dict that has the desired properties. This
would

1. Clarify and document the syntax and semantics.
2. Help with exploration and testing.
3. Provide a 'back-port' mechanism to current Python.
4. Give the proposal the benefit of practical experience.

I find this last very important, when we can do it. And we can, in
this case. Language changes are 'cast in stone' and hard to reverse.
And afterwards, on this list, we're sometime told that we've 'missed
the boat' for a particular change.

Let's take the benefit of a reference pure Python implementation, when we can.

Steven D'A. Please would you include or respond to this suggestion, in
the next revision of the PEP.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Antoine Pitrou
On Thu, 21 Mar 2019 17:59:41 +
Rhodri James  wrote:
> 
> >> And to those who support this PEP, code examples where a dict merge
> >> operator will help are most welcome!  
> 
> I don't use Python often enough to have much to offer, I'm afraid.  The 
> sort of occasion I would use dict merging is passing modified 
> environments to subcommands.  Something like:
> 
> def process():
>  if time_to_do_thing1():
>  thing1(base_env + thing1_env_stuff + env_tweaks)
>  if time_to_do_thing2():
>  thing2(base_env + thing2_env_stuff + env_tweaks)
> 
> ...and so on.  The current syntax for doing this is a tad verbose:
> 
> def process():
>  if time_to_do_thing1():
>  env = base_env.copy()
>  env.update(thing1_env_stuff)
>  env.update(env_tweaks)
>  thing1(env)
>   del env
>  if time_to_do_thing2():
>  env = base_env.copy()
>  env.update(thing2_env_stuff)
>  env.update(env_tweaks)
>  thing2(env)
>  del env

Ah, you convinced me there is a use case indeed (though `del env` isn't
necessary above).  I would still prefer something that's not an
operator, but I agree there is potential to improve the current state
of affairs.

Note that, if you're able to live with a third-party dependency, the
`toolz` package has what you need (and lots of other things too):
https://toolz.readthedocs.io/en/latest/api.html#toolz.dicttoolz.merge

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Rhodri James

On 21/03/2019 17:59, Rhodri James wrote:

def process():
     if time_to_do_thing1():
     thing1(base_env + thing1_env_stuff + env_tweaks)
     if time_to_do_thing2():
     thing2(base_env + thing2_env_stuff + env_tweaks)

...and so on.  The current syntax for doing this is a tad verbose:

def process():
     if time_to_do_thing1():
     env = base_env.copy()
     env.update(thing1_env_stuff)
     env.update(env_tweaks)
     thing1(env)
 del env
     if time_to_do_thing2():
     env = base_env.copy()
     env.update(thing2_env_stuff)
     env.update(env_tweaks)
     thing2(env)
     del env


Of course I forgot:

def process():
if time_to_do_thing1():
thing1({**base_env, **thing1_env_stuff, **env_tweaks})
if time_to_do_thing2():
thing2({**base_env, **thing2_env_stuff, **env_tweaks})

...which says something about how memorable that syntax is.

--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Brandt Bucher
I'd also like to add what I consider to be another point in favor of an
operator:

Throughout all of these related threads, I have seen many typos and
misspellings of current dict merging idioms, from messing up the number of
asterisks in "{**a, **b}", to even Guido(!) accidentally writing the common
copy/update idiom as

d = d1.copy()
d = d1.update(d2)

in a thoughtful email... and it was then copied-and-pasted (unquoted and
verbatim) by others!

I still have yet to see somebody (even those who claim to be confused by
it) mess up the PEP's current definition of "+" or "+=" in this context.

Brandt
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Rhodri James

On 21/03/2019 17:06, Antoine Pitrou wrote:

On Fri, 22 Mar 2019 03:42:00 +1100
Steven D'Aprano  wrote:


For those who oppose the + operator, it will help me if you made it
clear whether it is *just* the + symbol you dislike, and would accept
the | operator instead, or whether you hate the whole operator concept
regardless of how it is spelled.


I'd rather see a method.  Dict merging just doesn't occur often enough
that an operator is desirable for it.


Analogous to the relationship between list.sort() and sorted(), I can't 
help but think that a dict.merge() method would be a terrible idea.  A 
merged() function is more defensible.



And to those who support this PEP, code examples where a dict merge
operator will help are most welcome!


I don't use Python often enough to have much to offer, I'm afraid.  The 
sort of occasion I would use dict merging is passing modified 
environments to subcommands.  Something like:


def process():
if time_to_do_thing1():
thing1(base_env + thing1_env_stuff + env_tweaks)
if time_to_do_thing2():
thing2(base_env + thing2_env_stuff + env_tweaks)

...and so on.  The current syntax for doing this is a tad verbose:

def process():
if time_to_do_thing1():
env = base_env.copy()
env.update(thing1_env_stuff)
env.update(env_tweaks)
thing1(env)
del env
if time_to_do_thing2():
env = base_env.copy()
env.update(thing2_env_stuff)
env.update(env_tweaks)
thing2(env)
del env

--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Dan Sommers

On 3/21/19 1:01 PM, Jonathan Fine wrote:

Rémi Lapeyre wrote:


Not matter the notation you end up choosing, I think this code:
https://github.com/jpadilla/pyjwt/blob/master/jwt/utils.py#L71-L81
[...] would greatly benefit from a new merge to merge dicts.


I've looked at the merge_dict defined in this code. It's similar to

 def gapfill(self, other):

 # See also: https://cobrapy.readthedocs.io/en/latest/gapfilling.html
 # Cobra's gapfill adds items to a model, to meet a requirement.

 for key in other.keys():
 if key not in self:
 self[key] = other[key]

(This is code I've written, that's not yet on PyPi.)  The usage is
different. Instead of writing one of
  aaa = merge_dict(aaa, bbb)
  ccc = merge_dict(aaa, bbb)
you write one of
  gapfill(aaa, bbb)
  aaa.gapfill(bbb)  # If gapfill added to dict methods.

With merge_dict, you never really know if ccc is the same object as
aaa, or a different one. Sometimes this is important.

With gapfill, you get the same behaviour as the already familiar and
loved dict.update. But of course with a different merge rule.


With gapfill, I can never remeber whether it's gapfill(aaa,
bbb) or gapfill(bbb, aaa).  This is always important.  :-)

At least with aaa.gapfill(bbb), I have some sense of the
"direction" of the asymmetry, or I would if I had some frame
of reference into which to put the "gapfill" operation.
(With the proposed + or | operator syntax, that gets lost.)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Stephen J. Turnbull
Chris Angelico writes:

 > ... then, in the interests of productive discussion, could you please
 > explain? What is it about dict addition that makes it harder to
 > understand than other addition?

Antoine didn't say what dict addition does is harder to understand
than other addition.  He said he wants to understand it without
knowing what it does.

I can't say for sure what he means precisely, but I take it that he
wants dict "+" to obey certain regularities that other instances of
"+" do, possibly including outside of Python.  As you'll see I find it
hard to make this precise, but it's a pretty strong feeling for me, as
well.

To me, those regularities include associativity (satisfied in Python
except for floats) and commutativity where possible (integers and I
believe floats do satisfy it, while strings cannot and other sequences
in Python in general do not, although they very often do in
mathematics).

For mappings, the mathematical meaning of "+" is usually pointwise.
This wouldn't make sense for strings (interpreted as mappings from a
prefix of the natural numbers) at all except that by accident in
Python s1[n] + s2[n] does make sense, but not pointwise (because the
length of the result is 2, not 1, for each n).

For sequences in general pointwise doesn't make sense (there's no
restriction to homogeneous sequences, and if there were, like strings
it's not clear that the elements would be summable in an appropriate
sense).  But concatenation always makes sense, especially by analogy
to the somehow (IMO) canonical case of strings.  For sets, the only
plausible interpretation of "addition" is union, but in fact Python
used .add asymmetrically as "add to", not "add together" (self is a
set, argument is a generic object), and the union operator is "|", not
"+".

For dictionaries, neither pointwise addition nor concatenation makes
sense in general, and update is "too asymmetric" for my taste, and has
no analog in the usual algebras of mappings.

In some sense string concatenation, though noncommutative, doesn't
lose information, and it does obey a sort of antisymmetry in that
a + b == reversed(reversed(b) + reversed(a)).  Dictionary update does
lose the original settings.

If people really think it's so important to spell

d = d0.copy()
d.update(d1)

as "d0 + d1" despite the noncommutativity (and the availability of
"{**d0, **d1}" for "true" dicts), and by extension the redundant "d |=
d1" for "d.update(d1)", I won't get terribly upset, but I will be sad
because it offends my sense of "beautiful code" (including TOOWTDI,
where "+" for dicts would violate both the "obvious" and the
parenthetical "only one" conditions IMO).  I would consider it a wart
in the same way that many people consider str.join a wart, as it
breaks even more of the regularities I associate with "+" than string
concatenation does.

Again, I don't know what Antoine meant, but I might say the same kind
of thing in the same words, and the above is what I would mean.

Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Jonathan Fine
Brandt Bucher wrote:

> Before:
>
> tmp = keep.copy()
> tmp.update(separate)
> result = function(param=tmp)
> del tmp

> After:
>
> result = f(param=keep+separate)

I'd rewrite this example as:

   Before:
   fn(param={**keep, **separate})

   After:
   fn(param=keep + separate)

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Jonathan Fine
Rémi Lapeyre wrote:

> Not matter the notation you end up choosing, I think this code:
> https://github.com/jpadilla/pyjwt/blob/master/jwt/utils.py#L71-L81
> [...] would greatly benefit from a new merge to merge dicts.

I've looked at the merge_dict defined in this code. It's similar to

def gapfill(self, other):

# See also: https://cobrapy.readthedocs.io/en/latest/gapfilling.html
# Cobra's gapfill adds items to a model, to meet a requirement.

for key in other.keys():
if key not in self:
self[key] = other[key]

(This is code I've written, that's not yet on PyPi.)  The usage is
different. Instead of writing one of
 aaa = merge_dict(aaa, bbb)
 ccc = merge_dict(aaa, bbb)
you write one of
 gapfill(aaa, bbb)
 aaa.gapfill(bbb)  # If gapfill added to dict methods.

With merge_dict, you never really know if ccc is the same object as
aaa, or a different one. Sometimes this is important.

With gapfill, you get the same behaviour as the already familiar and
loved dict.update. But of course with a different merge rule.
-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Brandt Bucher
>
> And to those who support this PEP, code examples where a dict merge
> operator will help are most welcome!


I would definitely include the example you alluded to in the operators
thread:

Before:

tmp = keep.copy()
tmp.update(separate)
result = function(param=tmp)
del tmp

After:

result = f(param=keep+separate)

Thanks for drafting the PEP for this. There seems to be a bit of an echo in
these 5+ threads, and your commentary has definitely been more
constructive/original than most. Looking forward to the next revision!

Brandt

On Thu, Mar 21, 2019 at 9:42 AM Steven D'Aprano  wrote:

> I'd like to make a plea to people:
>
> I get it, there is now significant opposition to using the + symbol for
> this proposed operator. At the time I wrote the first draft of the PEP,
> there was virtually no opposition to it, and the | operator had very
> little support. This has clearly changed.
>
> At this point I don't think it is productive to keep making subjective
> claims that + will be more confusing or surprising. You've made your
> point that you don't like it, and the next draft^1 of the PEP will make
> that clear.
>
> But if you have *concrete examples* of code that currently is easy to
> understand, but will be harder to understand if we add dict.__add__,
> then please do show me!
>
> For those who oppose the + operator, it will help me if you made it
> clear whether it is *just* the + symbol you dislike, and would accept
> the | operator instead, or whether you hate the whole operator concept
> regardless of how it is spelled.
>
> And to those who support this PEP, code examples where a dict merge
> operator will help are most welcome!
>
>
>
>
> ^1 Coming Real Soon Now™.
>
>
> --
> Steven
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Paul Moore
On Thu, 21 Mar 2019 at 17:27, Rémi Lapeyre  wrote:
>
> Le 21 mars 2019 à 17:43:31, Steven D'Aprano
> (st...@pearwood.info(mailto:st...@pearwood.info)) a écrit:
>
> > I'd like to make a plea to people:
> >
> > I get it, there is now significant opposition to using the + symbol for
> > this proposed operator. At the time I wrote the first draft of the PEP,
> > there was virtually no opposition to it, and the | operator had very
> > little support. This has clearly changed.
> >
> > At this point I don't think it is productive to keep making subjective
> > claims that + will be more confusing or surprising. You've made your
> > point that you don't like it, and the next draft^1 of the PEP will make
> > that clear.
> >
> > But if you have *concrete examples* of code that currently is easy to
> > understand, but will be harder to understand if we add dict.__add__,
> > then please do show me!
> >
> > For those who oppose the + operator, it will help me if you made it
> > clear whether it is *just* the + symbol you dislike, and would accept
> > the | operator instead, or whether you hate the whole operator concept
> > regardless of how it is spelled.
>
> Thanks for the work you are doing on this PEP and for debunking my
> misconceptions regarding types, I’m currently learning a lot about them.
>
> I don’t know if it matters but I’m in favor of the method
>
> > And to those who support this PEP, code examples where a dict merge
> > operator will help are most welcome!
>
> Not matter the notation you end up choosing, I think this code:
> https://github.com/jpadilla/pyjwt/blob/master/jwt/utils.py#L71-L81
>
> which is part of a widely used library to validate JWTs would greatly
> benefit from a new merge to merge dicts. (This package is 78 on
> https://hugovk.github.io/top-pypi-packages/)

It's already got a function that does the job. How much benefit is
there *really* from being able to replace it with d1 + d2 once you
drop support for Python < 3.8? But point taken that new code would
have been able to avoid the function in the first place.

... or would it?

def merge_dict(original, updates):
if not updates:
return original

With the  + operator. d1 + None will fail with an error. With your
code, updates=None means "return the original unchanged". Does that
matter with your current code?

The point is that in many real world cases, you'd write a function
*anyway*, to handle corner cases, and a new operator doesn't make much
difference at that point.

Having said all of that, I'm mostly indifferent to the idea of having
a built in "dictionary merge" capability - I doubt I'd use it *much*,
but if it were there I'm sure I'd find useful it on the odd occasion.
I'm somewhat against an operator, I really don't see why this couldn't
be a method (although the asymmetry in d1.merge(d2) makes me have a
mild preference for a class method or standalone function). I can't
form an opinion between + and |, I find | significantly uglier (I tend
to avoid using it for sets, in favour of the union method) but I am
mildly uncomfortable with more overloading of +.

Serious suggestion - why not follow the lead of sets, and have *both*
an operator and a method? And if you think that's a bad idea, it would
be worth considering *why* it's a bad idea for dictionaries, when it's
OK for sets (and "well, I didn't like it when sets did it" isn't
sufficient ;-))

And having said that, I'll go back to lurking and not really caring
one way or the other.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Jonathan Fine
Steven D'Aprano wrote:

> But if you have *concrete examples* of code that currently is easy to
> understand, but will be harder to understand if we add dict.__add__,
> then please do show me!

# What does this do?
 >>> items. update(points)

# And what does this do?
>>> items += points

What did you get? Here's one possible context.

>>> Point = namedtuple('Point', ['x', 'y'])
>>> p, q, r = Point(1,2), Point(3, 4), Point(5, 6)
>>> points = set([p, q, r])
>>> points
{Point(x=1, y=2), Point(x=5, y=6), Point(x=3, y=4)}
>>> items = dict(a=4, b=8)
-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Rémi Lapeyre
Le 21 mars 2019 à 17:43:31, Steven D'Aprano
(st...@pearwood.info(mailto:st...@pearwood.info)) a écrit:

> I'd like to make a plea to people:
>
> I get it, there is now significant opposition to using the + symbol for
> this proposed operator. At the time I wrote the first draft of the PEP,
> there was virtually no opposition to it, and the | operator had very
> little support. This has clearly changed.
>
> At this point I don't think it is productive to keep making subjective
> claims that + will be more confusing or surprising. You've made your
> point that you don't like it, and the next draft^1 of the PEP will make
> that clear.
>
> But if you have *concrete examples* of code that currently is easy to
> understand, but will be harder to understand if we add dict.__add__,
> then please do show me!
>
> For those who oppose the + operator, it will help me if you made it
> clear whether it is *just* the + symbol you dislike, and would accept
> the | operator instead, or whether you hate the whole operator concept
> regardless of how it is spelled.

Thanks for the work you are doing on this PEP and for debunking my
misconceptions regarding types, I’m currently learning a lot about them.

I don’t know if it matters but I’m in favor of the method

> And to those who support this PEP, code examples where a dict merge
> operator will help are most welcome!

Not matter the notation you end up choosing, I think this code:
https://github.com/jpadilla/pyjwt/blob/master/jwt/utils.py#L71-L81

which is part of a widely used library to validate JWTs would greatly
benefit from a new merge to merge dicts. (This package is 78 on
https://hugovk.github.io/top-pypi-packages/)

Rémi

> ^1 Coming Real Soon Now™.
>
>
> --
> Steven
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Antoine Pitrou
On Fri, 22 Mar 2019 03:42:00 +1100
Steven D'Aprano  wrote:
> 
> For those who oppose the + operator, it will help me if you made it 
> clear whether it is *just* the + symbol you dislike, and would accept 
> the | operator instead, or whether you hate the whole operator concept 
> regardless of how it is spelled.

I'd rather see a method.  Dict merging just doesn't occur often enough
that an operator is desirable for it.

> And to those who support this PEP, code examples where a dict merge 
> operator will help are most welcome!

Yes, I still have no idea why this operator would supposedly be
useful.  How many dict merges do you write per month?

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Steven D'Aprano
I'd like to make a plea to people:

I get it, there is now significant opposition to using the + symbol for 
this proposed operator. At the time I wrote the first draft of the PEP, 
there was virtually no opposition to it, and the | operator had very 
little support. This has clearly changed.

At this point I don't think it is productive to keep making subjective 
claims that + will be more confusing or surprising. You've made your 
point that you don't like it, and the next draft^1 of the PEP will make 
that clear.

But if you have *concrete examples* of code that currently is easy to 
understand, but will be harder to understand if we add dict.__add__, 
then please do show me!

For those who oppose the + operator, it will help me if you made it 
clear whether it is *just* the + symbol you dislike, and would accept 
the | operator instead, or whether you hate the whole operator concept 
regardless of how it is spelled.

And to those who support this PEP, code examples where a dict merge 
operator will help are most welcome!




^1 Coming Real Soon Now™.


-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Steven D'Aprano
On Thu, Mar 21, 2019 at 03:16:44PM +0200, Serhiy Storchaka wrote:
> 21.03.19 14:51, Chris Angelico пише:
> >... then, in the interests of productive discussion, could you please
> >explain? What is it about dict addition that makes it harder to
> >understand than other addition?
> 
> Currently the + operator has 2 meanings for builtin types (both are 
> widely used), after adding it for dicts it will have 3 meanings.

Just two meanings? I get at least eight among the builtins:

- int addition;
- float addition;
- complex addition;
- string concatenation;
- list concatenation;
- tuple concatenation;
- bytes concatenation;
- bytearray concatenation.


I suppose if you cover one eye and focus on the "big picture", ignoring 
vital factors like "you can't add a list to a string" and "float 
addition and int addition aren't precisely the same", we might pretend 
that this is just two operations:

- numeric addition;
- sequence concatenation.

But in practice, when reading code, it's usually not enough to know that 
some use of the + operator means "concatenation", you need to know 
*what* is being concatenated. There's no point trying to add a tuple if 
a bytearray is required.


> 3 > 2, is not?

Okay, but how does this make it harder to determine what a piece of code 
using + does? Antoine insists that *if we allow dict addition*, then we 
won't be able to tell what 

spam + eggs  # for example

does unless we know what spam and eggs are. This is very true. But it is 
*equally true today*, right now, and its been equally true going back to 
Python 1.0 or before.

This proposed change doesn't add any uncertainty that doesn't already 
exist, nor will it make code that is clear today less clear tomorrow.^1

And don't forget that Python allows us to create non-builtin types that 
overload operators. If you don't know what spam and eggs are, you can't 
assume they are builtins. With operator overloading, any operator can 
mean literally anything at all. In practice though, this rarely becomes 
a serious problem.

Is there a significant increase in difficulty between the current 
situation:

# Is this addition or concatenation or something else?
spam + eggs

versus the proposed:

# Is this addition or concatenation or merge or something else?
spam + eggs

Obviously there's *one more builtin* to consider, but I don't think that 
changes the process of understanding the meaning of the operation.

I think that the problem you and Antoine fear ("dict.__add__ will make 
it harder to read code") requires a process that goes something like 
this:


1. Here's a mysterious "spam + eggs" operation we need to understand.
2. For each operation in ("numeric addition", "concatenation"):
3. assume + represents that operation;
4. if we understand the spam+eggs expression now, break


If that's how we read code, then adding one more operation would make it 
harder to understand. We'd have to loop three times, not twice:

2. For each operation in ("numeric addition", "concatenation", "dict merging"):

Three is greater than two, so we may have to do more work to understand 
the code. But I don't think that's how people actually read code. I 
think they do this:

1. Here's a mysterious "spam + eggs" operation we need to understand.
2. Read the code to find out what spam and eggs are.
3. Knowing what they are (tuples, lists, floats, etc) immediately tells 
   you what the plus operator does; at worst, a programmer unfamiliar 
   with the type may need to read the docs.

Adding dict.__add__ doesn't make it any harder to work out what the 
operands spam and eggs are. The process we go through to determine what 
the operands are remains the same:

- if one of operands is a literal, that gives you a strong hint that 
  the other is the same type;
- the names or context may make it clear ("header + text" probably 
  isn't doing numeric addition);
- read back through the code looking for where the variables are 
  defined; etc.

That last bit isn't always easy. People can write obfuscated, complex 
code using poor or misleading names. But allowing dict.__add__ doesn't 
make it more obfuscated or more complex. Usually the naming and context 
will make it clear. Most code is not terrible.

At worst, there will be a transition period where people have a 
momentary surprise:

"Wait, what, these are dicts??? How can you add dicts???"

but then they will read the docs (or ask StackOverflow) and the second 
time they see it, it shouldn't be a surprise.




^1 That's my assertion, but if anyone has a concrete example of actual 
code which is self-evident today but will become ambiguous if this 
proposal goes ahead, please show me!


-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Serhiy Storchaka

21.03.19 15:24, Chris Angelico пише:

On Fri, Mar 22, 2019 at 12:17 AM Serhiy Storchaka  wrote:


21.03.19 14:51, Chris Angelico пише:

... then, in the interests of productive discussion, could you please
explain? What is it about dict addition that makes it harder to
understand than other addition?


Currently the + operator has 2 meanings for builtin types (both are
widely used), after adding it for dicts it will have 3 meanings.

3 > 2, is not?


I suppose you could call it two (numeric addition and sequence
concatenation), but there are subtleties to the way that lists
concatenate that don't apply to strings (esp since lists are mutable),
so I'd call it at least three already.


I do not understand what are these subtleties that you treat list 
concatenation different from string concatenation. Could you please explain?


In any case, it does not matter how you count meanings, n + 1 > n.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Nathan Schneider
On Thu, Mar 21, 2019 at 9:17 AM Serhiy Storchaka 
wrote:

> 21.03.19 14:51, Chris Angelico пише:
> > ... then, in the interests of productive discussion, could you please
> > explain? What is it about dict addition that makes it harder to
> > understand than other addition?
>
> Currently the + operator has 2 meanings for builtin types (both are
> widely used), after adding it for dicts it will have 3 meanings.
>
> 3 > 2, is not?
>

It depends how abstractly you define the "meanings".

If you define + as "arithmetic addition" and "sequence concatenation", then
yes, there are 2. But novices have to learn that the same concatenation
operator applies to strings as well as lists/tuples. And when reading x +
y, it is probably relevant whether x and y are numbers, strings, or
sequence containers like lists.

The proposal would generalize "sequence concatenation" to something like
"asymmetric sequence/collection combination". (Asymmetric because d1 + d2
may not equal d2 + d1.) It seems a natural extension to me, though the |
alternative is also reasonable (interpreted as taking the OR of keys in the
two dicts; but unlike unioning two sets, the dict-merge operator would be
asymmetric). The third proposed alternative, <<, has no "baggage" from an
existing use as a combination operator, but at the same time it is a more
obscure choice.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Chris Angelico
On Fri, Mar 22, 2019 at 12:17 AM Serhiy Storchaka  wrote:
>
> 21.03.19 14:51, Chris Angelico пише:
> > ... then, in the interests of productive discussion, could you please
> > explain? What is it about dict addition that makes it harder to
> > understand than other addition?
>
> Currently the + operator has 2 meanings for builtin types (both are
> widely used), after adding it for dicts it will have 3 meanings.
>
> 3 > 2, is not?

I suppose you could call it two (numeric addition and sequence
concatenation), but there are subtleties to the way that lists
concatenate that don't apply to strings (esp since lists are mutable),
so I'd call it at least three already. And what about non-builtin
types? You can add two numpy arrays and it does pairwise addition,
quite different from how lists add together. But in every case, the +
operator means "add these things together". It will be the same with
dicts: you add the dicts together.

Antoine has stated that the problem is NOT understanding what
dict.__add__ does, so I am at a loss as to what the problem IS. We
*already* have many different definitions of "add", according to the
data types involved. That is exactly what polymorphism is for. Why is
it such a bad thing for a dict?

Now, my own opinion is that | would be a better operator than +, but
it's only a weak preference, and I'd be happy with either. Also, to my
understanding, the concerns about "what does addition mean" apply
identically to "what does Or mean", but as we've already seen, my
understanding doesn't currently extend as far as comprehending this
issue. Hence asking.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Rhodri James

On 21/03/2019 11:34, Antoine Pitrou wrote:

On Wed, 20 Mar 2019 15:46:24 -1000
Christopher Barker 
wrote:



This is precisely why I worded my question this way: what has changed
in the last 20 years that make a "+" dict operator more compelling
today than it was?  Do we merge dicts much more frequently than we
did?


The analogy doesn't hold because @ was a new operator -- a MUCH bigger
change than dimply defining the use of + (or | ) for dicts.


But it's less disruptive when reading code, because "x @ y" is
unambiguous: it's a matrix multiplication.  "x + y" can be many
different things, and now it can be one more thing.


"x @ y" is unambiguous once you know what it means.  Until then, it's 
just mysterious.



I wouldn't mind the new operator if its meaning was clear-cut.  But

here we have potential for confusion, both for writers and readers of
code.
  


but it's NOT a new operator, it is making use of an existing one, and sure
you could guess at a couple meanings, but the merge one is probably one of
the most obvious to guess, and one quick test and you know -- I really
can't see it being a ongoing source of confusion.


Did you actually read what I said?  The problem is not to understand
what dict.__add__ does.  It's to understand what code using the +
operator does, without knowing upfront whether the inputs are dicts.


Welcome to polymorphism.

--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Serhiy Storchaka

21.03.19 14:51, Chris Angelico пише:

... then, in the interests of productive discussion, could you please
explain? What is it about dict addition that makes it harder to
understand than other addition?


Currently the + operator has 2 meanings for builtin types (both are 
widely used), after adding it for dicts it will have 3 meanings.


3 > 2, is not?

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Antoine Pitrou
On Thu, 21 Mar 2019 23:51:12 +1100
Chris Angelico  wrote:
> On Thu, Mar 21, 2019 at 11:45 PM Antoine Pitrou  wrote:
> >
> > On Thu, 21 Mar 2019 23:35:36 +1100
> > Chris Angelico  wrote:  
> > > On Thu, Mar 21, 2019 at 10:35 PM Antoine Pitrou  
> > > wrote:  
> > > > > but it's NOT a new operator, it is making use of an existing one, and 
> > > > > sure
> > > > > you could guess at a couple meanings, but the merge one is probably 
> > > > > one of
> > > > > the most obvious to guess, and one quick test and you know -- I really
> > > > > can't see it being a ongoing source of confusion.  
> > > >
> > > > Did you actually read what I said?  The problem is not to understand
> > > > what dict.__add__ does.  It's to understand what code using the +
> > > > operator does, without knowing upfront whether the inputs are dicts.  
> > >
> > > The + operator adds two things together. I don't understand the issue 
> > > here.  
> >
> > I'm not expecting you to understand, either.
> >  
> 
> ... then, in the interests of productive discussion, could you please
> explain? What is it about dict addition that makes it harder to
> understand than other addition?

"Productive discussion" is something that requires mutual implication.
Asking me to repeat exactly what I spelled out above (and that you
even quoted) is not productive.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Chris Angelico
On Thu, Mar 21, 2019 at 11:45 PM Antoine Pitrou  wrote:
>
> On Thu, 21 Mar 2019 23:35:36 +1100
> Chris Angelico  wrote:
> > On Thu, Mar 21, 2019 at 10:35 PM Antoine Pitrou  wrote:
> > > > but it's NOT a new operator, it is making use of an existing one, and 
> > > > sure
> > > > you could guess at a couple meanings, but the merge one is probably one 
> > > > of
> > > > the most obvious to guess, and one quick test and you know -- I really
> > > > can't see it being a ongoing source of confusion.
> > >
> > > Did you actually read what I said?  The problem is not to understand
> > > what dict.__add__ does.  It's to understand what code using the +
> > > operator does, without knowing upfront whether the inputs are dicts.
> >
> > The + operator adds two things together. I don't understand the issue here.
>
> I'm not expecting you to understand, either.
>

... then, in the interests of productive discussion, could you please
explain? What is it about dict addition that makes it harder to
understand than other addition?

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Antoine Pitrou
On Thu, 21 Mar 2019 23:35:36 +1100
Chris Angelico  wrote:
> On Thu, Mar 21, 2019 at 10:35 PM Antoine Pitrou  wrote:
> > > but it's NOT a new operator, it is making use of an existing one, and sure
> > > you could guess at a couple meanings, but the merge one is probably one of
> > > the most obvious to guess, and one quick test and you know -- I really
> > > can't see it being a ongoing source of confusion.  
> >
> > Did you actually read what I said?  The problem is not to understand
> > what dict.__add__ does.  It's to understand what code using the +
> > operator does, without knowing upfront whether the inputs are dicts.  
> 
> The + operator adds two things together. I don't understand the issue here.

I'm not expecting you to understand, either.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Chris Angelico
On Thu, Mar 21, 2019 at 10:35 PM Antoine Pitrou  wrote:
> > but it's NOT a new operator, it is making use of an existing one, and sure
> > you could guess at a couple meanings, but the merge one is probably one of
> > the most obvious to guess, and one quick test and you know -- I really
> > can't see it being a ongoing source of confusion.
>
> Did you actually read what I said?  The problem is not to understand
> what dict.__add__ does.  It's to understand what code using the +
> operator does, without knowing upfront whether the inputs are dicts.

The + operator adds two things together. I don't understand the issue here.

You can add integers: 1 + 2 == 3
You can add floats: 0.5 + 1.25 == 1.75
You can add lists: [1,2] + [3,4] == [1,2,3,4]
You can add strings: "a" + "b" == "ab"

And soon you'll be able to add dictionaries. The exact semantics need
to be defined, but it's not fundamentally changing how you interpret
the + operator. I don't understand the panic here - or rather, I don't
understand why it's happening NOW, not back when lists got the ability
to be added (if that wasn't in the very first release).

Conversely, if it's the | operator, it's a matter of merging, and the
same is true. You can merge integers, treating them as bit sets. You
can merge sets. And now you'll be able to merge dictionaries. Same
same.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-21 Thread Antoine Pitrou
On Wed, 20 Mar 2019 15:46:24 -1000
Christopher Barker 
wrote:
> 
> > This is precisely why I worded my question this way: what has changed
> > in the last 20 years that make a "+" dict operator more compelling
> > today than it was?  Do we merge dicts much more frequently than we
> > did?  
> 
> The analogy doesn't hold because @ was a new operator -- a MUCH bigger
> change than dimply defining the use of + (or | ) for dicts.

But it's less disruptive when reading code, because "x @ y" is
unambiguous: it's a matrix multiplication.  "x + y" can be many
different things, and now it can be one more thing.

> I wouldn't mind the new operator if its meaning was clear-cut.  But
> > here we have potential for confusion, both for writers and readers of
> > code.
> >  
> 
> but it's NOT a new operator, it is making use of an existing one, and sure
> you could guess at a couple meanings, but the merge one is probably one of
> the most obvious to guess, and one quick test and you know -- I really
> can't see it being a ongoing source of confusion.

Did you actually read what I said?  The problem is not to understand
what dict.__add__ does.  It's to understand what code using the +
operator does, without knowing upfront whether the inputs are dicts.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-20 Thread Christopher Barker
On Sat, Mar 16, 2019 at 12:39 AM Antoine Pitrou  wrote:

> On Sat, 16 Mar 2019 01:41:59 +1100
> Steven D'Aprano  wrote:
>


> > Matrix multiplication is a perfect example: adding the @ operator could
> > have been done in Python 0.1 if anyone had thought of it, but it took 15
> > years of numerical folk "whinging" about the lack until it happened:
>
> Not so perfect, as the growing use of Python for scientific computing
> has made it much more useful to promote a dedicated matrix
> multiplication operator than, say, 15 or 20 years ago.
>

Theres more to it than that, really, but not really relevant here...


> This is precisely why I worded my question this way: what has changed
> in the last 20 years that make a "+" dict operator more compelling
> today than it was?  Do we merge dicts much more frequently than we
> did?


The analogy doesn't hold because @ was a new operator -- a MUCH bigger
change than dimply defining the use of + (or | ) for dicts.

I wouldn't mind the new operator if its meaning was clear-cut.  But
> here we have potential for confusion, both for writers and readers of
> code.
>

but it's NOT a new operator, it is making use of an existing one, and sure
you could guess at a couple meanings, but the merge one is probably one of
the most obvious to guess, and one quick test and you know -- I really
can't see it being a ongoing source of confusion.

-CHB

-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-16 Thread Antoine Pitrou
On Sat, 16 Mar 2019 03:44:02 +1100
Steven D'Aprano  wrote:
> On Fri, Mar 15, 2019 at 12:34:45PM +0100, Antoine Pitrou wrote:
> > On Thu, 7 Mar 2019 10:58:02 +1100
> > Chris Angelico  wrote:  
> > > 
> > > Lots of words that basically say: Stuff wouldn't be perfectly pure.  
> > 
> > Chris, please learn to think twice before contributing what is
> > essentially a trivialization of someone else's arguments.  You're not
> > doing anything useful here, and are just sounding like an asshole who
> > wants to shut people up.  
> 
> I don't think you are being fair here, and I'd rather avoid getting into 
> unhelpful arguments about tone and whether Chris is "trivializing" (a 
> perjorative term) or "simplifying" (a more neutral term) Josh's 
> position. But if you feel that Chris (and I) have missed parts of Josh's 
> argument, then by all means point out what we missed.

When someone posts an elaborate argument (regardless of whether they are
right or not) and someone else responds a one-liner that reduces it to
"lots of words" and claims to rephrase it as a short caricatural
statement, then it seems fair to me to characterize it as
"trivializing".

But if you feel that I missed a subtlety in Chris' position, and if
you feel he was more respectful of the OP than I felt he was, then by
all means point out what I missed.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-16 Thread Antoine Pitrou
On Sat, 16 Mar 2019 01:59:07 +1100
Steven D'Aprano  wrote:
> On Fri, Mar 15, 2019 at 12:25:22PM +0100, Antoine Pitrou wrote:
> 
> > Yeah, well I do think "+=" for lists was a mistake.  I *still* have
> > trouble remembering the exact difference between "list +=" and
> > "list.extend" (yes, there is one: one accepts more types than the
> > other... which one it is, and why, I never remember;  
> 
> Both accept arbitrary iterables, and the documentation suggests that 
> they are the same:
> 
> https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
> 
> Perhaps you are thinking of the difference between list + list versus 
> list += iterable?

Hmm, it looks like I misremembered indeed.  Thanks for correcting this.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-16 Thread Antoine Pitrou
On Sat, 16 Mar 2019 01:41:59 +1100
Steven D'Aprano  wrote:
> 
> Matrix multiplication is a perfect example: adding the @ operator could 
> have been done in Python 0.1 if anyone had thought of it, but it took 15 
> years of numerical folk "whinging" about the lack until it happened:

Not so perfect, as the growing use of Python for scientific computing
has made it much more useful to promote a dedicated matrix
multiplication operator than, say, 15 or 20 years ago.

This is precisely why I worded my question this way: what has changed
in the last 20 years that make a "+" dict operator more compelling
today than it was?  Do we merge dicts much more frequently than we
did?  I don't think so.

> Or the infamous := operator, which ultimately is a useful but minor 
> syntactic and semantic change but generated a huge amount of debate, 
> argument and negativity.

... and is likely to be a mistake as well.  Justifying future mistakes
with past mistakes doesn't sound very reasonable ;-)

> I still remember being told in no uncertain terms by the core devs that 
> adding a clear() method to lists was a waste of time because there was 
> already a perfectly good way to spell it with slicing. And then ABCs 
> came along and now lists have a clear method. So opinions change too.

Not really the same problem.  The "+" dict operator is not
intuitively obvious in its meaning, while a "clear()" method on lists
is.

I wouldn't mind the new operator if its meaning was clear-cut.  But
here we have potential for confusion, both for writers and readers of
code.

> > Besides, if I have two dicts with e.g. lists as values, I *really*
> > dislike the fact that the + operator will clobber the values rather than
> > concatenate them.  It's a recipe for confusion.  
> 
> Are you confused that the update method clobbers list values rather than 
> concatenate them? I doubt that you are.
> 
> So why would it be confusing to say that + does a copy-and-update?

Because it's named "+" precisely.  You know, names are important. ;-)

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-16 Thread Stefan Krah
On Sat, Mar 16, 2019 at 09:04:22PM +1300, Greg Ewing wrote:
> Another random thought about this: Mathematicians use addition as a
> metaphor for quite a range of different things, but they tend to only
> use the symbols ∪ and ∩ for actual sets, or things that are very
> set-like. So maybe that's an argument for using '+' rather than '|'
> for dict merging.

If one views an ordered dict as an assoc list, '+' would mean prepending
the new values to the existing ones.

If one views an unordered dict as a set of ordered pairs, '|' would make
sense.


Stefan Krah




___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-16 Thread Greg Ewing

Another random thought about this: Mathematicians use addition as a
metaphor for quite a range of different things, but they tend to only
use the symbols ∪ and ∩ for actual sets, or things that are very
set-like. So maybe that's an argument for using '+' rather than '|'
for dict merging.

--
Greg

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Brett Cannon
On Fri, Mar 15, 2019 at 11:15 AM Steven D'Aprano 
wrote:

> On Fri, Mar 15, 2019 at 10:34:45AM -0700, Brett Cannon wrote:
>
> > Watch the tone please.
>
> Brett, you might have missed my comment about wanting to avoid unhelpful
> arguments about tone, but if you are going to complain about people's
> tone, the considerate thing to do is to say what it is that you're
> objecting to.
>

The phrasing of "just sounding like an asshole who wants to shut people up"
is unnecessary.


>
> Otherwise we're left guessing as to what it is and whether or not you
> are making an implied threat to apply the CoC.
>

No implied "threat". If it was an official warning then I would have said
so.


>
> I responded to Antoine's post earlier, but thought that it was a
> respectful disagreement. Do you think that's not the case?
>

I think it skirts the edge of being disrespectful, hence the request to
please be aware of how one comes across.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Steven D'Aprano
On Fri, Mar 15, 2019 at 10:34:45AM -0700, Brett Cannon wrote:

> Watch the tone please.

Brett, you might have missed my comment about wanting to avoid unhelpful 
arguments about tone, but if you are going to complain about people's 
tone, the considerate thing to do is to say what it is that you're 
objecting to.

Otherwise we're left guessing as to what it is and whether or not you 
are making an implied threat to apply the CoC.

I responded to Antoine's post earlier, but thought that it was a 
respectful disagreement. Do you think that's not the case?



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Brett Cannon
On Fri, Mar 15, 2019 at 4:36 AM Antoine Pitrou  wrote:

> On Thu, 7 Mar 2019 10:58:02 +1100
> Chris Angelico  wrote:
> >
> > Lots of words that basically say: Stuff wouldn't be perfectly pure.
>
> Chris, please learn to think twice before contributing what is
> essentially a trivialization of someone else's arguments.  You're not
> doing anything useful here, and are just sounding like an asshole who
> wants to shut people up.
>

Watch the tone please.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Terry Reedy

On 3/15/2019 11:21 AM, Steven D'Aprano wrote:

On Fri, Mar 15, 2019 at 11:54:51AM -0300, Andre Roberge wrote:

On Fri, Mar 15, 2019 at 11:42 AM Steven D'Aprano 
wrote:


[snip]

I still remember being told in no uncertain terms by the core devs that
adding a clear() method to lists was a waste of time because there was
already a perfectly good way to spell it with slicing. And then ABCs
came along and now lists have a clear method. So opinions change too.

I agree with the opinions expressed in the (partially) quoted message

but I don't think that this is how this particular change happened.

https://mail.python.org/pipermail/python-ideas/2009-April/003897.html


You proposed that in April 2009, but there was nothing added to the bug
tracker for 18 months until it was finally added by Terry Reedy in


Actually, I opened the tracker issue with a succinct message,
after the discussion and Guido's approval changed my mind.
https://bugs.python.org/issue10516
However, Eli Bendersky wrote the patch with help from others and then 
merged it.



November 2010, based on discussion in a completely different thread (one
about sets!):

https://mail.python.org/pipermail/python-ideas/2010-November/008722.html




--
Terry Jan Reedy

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Steven D'Aprano
On Fri, Mar 15, 2019 at 12:34:45PM +0100, Antoine Pitrou wrote:
> On Thu, 7 Mar 2019 10:58:02 +1100
> Chris Angelico  wrote:
> > 
> > Lots of words that basically say: Stuff wouldn't be perfectly pure.
> 
> Chris, please learn to think twice before contributing what is
> essentially a trivialization of someone else's arguments.  You're not
> doing anything useful here, and are just sounding like an asshole who
> wants to shut people up.

I don't think you are being fair here, and I'd rather avoid getting into 
unhelpful arguments about tone and whether Chris is "trivializing" (a 
perjorative term) or "simplifying" (a more neutral term) Josh's 
position. But if you feel that Chris (and I) have missed parts of Josh's 
argument, then by all means point out what we missed.

Josh, the same applies to you: I do want to give your objections a fair 
hearing in the updated PEP, so if you think I've missed something, 
please point it out.

In context, I think Chris' response was valid: he was responding to 
a post by Josh whose entire argument was that using + for dict merging 
is an abuse of the + symbol because it isn't like numeric addition.

If there is more to Josh's argument, can you point out to me what I have 
missed please? That's a genuine request, not a rhetorical question.

Here's Josh's argument:

https://mail.python.org/pipermail/python-ideas/2019-March/055733.html

and for context, here is Chris' dismissal of Josh's argument:

https://mail.python.org/pipermail/python-ideas/2019-March/055734.html

and his explanation of why he is dismissing it.

Chris is well within his right to dismiss an argument that doesn't 
impress him, which he did by summarizing it as "Stuff wouldn't be 
perfectly pure". (Pure in the sense of being like numeric addition.)

I think that's pretty much an accurate summary: Josh apparently doesn't 
like using + for anything that isn't purely like + for real numbers. He 
calls using + for concatentation a "minor abuse" of the operator and 
argues that it would be bad for dict meging to use + because merging has 
different properties to numeric addition. (He has also criticised the 
use of + for concatenation in at least one other post.)

He even gives qualified support for a dict merge operator:

"there's nothing wrong with making dict merges easier"

but just doesn't like the choice of + as the operator.

He's entitled to his opinion, and Chris is entitled to dismiss it. 


(Aside: your email appears to have broken threading. I'm not sure 
why, your other emails seem to be threaded okay.)


-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Steven D'Aprano
On Fri, Mar 15, 2019 at 11:54:51AM -0300, Andre Roberge wrote:
> On Fri, Mar 15, 2019 at 11:42 AM Steven D'Aprano 
> wrote:
> 
> > [snip]
> >
> > I still remember being told in no uncertain terms by the core devs that
> > adding a clear() method to lists was a waste of time because there was
> > already a perfectly good way to spell it with slicing. And then ABCs
> > came along and now lists have a clear method. So opinions change too.
> >
> > I agree with the opinions expressed in the (partially) quoted message
> but I don't think that this is how this particular change happened.
> 
> https://mail.python.org/pipermail/python-ideas/2009-April/003897.html

You proposed that in April 2009, but there was nothing added to the bug 
tracker for 18 months until it was finally added by Terry Reedy in 
November 2010, based on discussion in a completely different thread (one 
about sets!):

https://mail.python.org/pipermail/python-ideas/2010-November/008722.html

Contrary-wise, a few years earlier the same request had been roundly 
dismissed by core-devs and Python luminaries as "inane", "redundant" and 
"trivial".

https://mail.python.org/pipermail/python-list/2006-April/356236.html

People can change their mind -- something that is dismissed one year may 
be accepted some years later on.



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Steven D'Aprano
On Fri, Mar 15, 2019 at 12:25:22PM +0100, Antoine Pitrou wrote:

> Yeah, well I do think "+=" for lists was a mistake.  I *still* have
> trouble remembering the exact difference between "list +=" and
> "list.extend" (yes, there is one: one accepts more types than the
> other... which one it is, and why, I never remember;

Both accept arbitrary iterables, and the documentation suggests that 
they are the same:

https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types

Perhaps you are thinking of the difference between list + list versus 
list += iterable?


[...]
> There is a virtue to
> 
> """There should be one-- and preferably only one --obvious way to do
> it"""

"It" here refers to two different things:

"I want to update a dict in place":

The Obvious Way is to use the update method; the fact that += works as 
well is just a side-effect of the way augmented assignments are defined.

"I want a new dict that merges two existing dicts":

The Obvious Way is to use the merge operator (possibly spelled + but 
that's not written in stone yet).



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Andre Roberge
On Fri, Mar 15, 2019 at 11:42 AM Steven D'Aprano 
wrote:

> [snip]
>
> I still remember being told in no uncertain terms by the core devs that
> adding a clear() method to lists was a waste of time because there was
> already a perfectly good way to spell it with slicing. And then ABCs
> came along and now lists have a clear method. So opinions change too.
>
> I agree with the opinions expressed in the (partially) quoted message
but I don't think that this is how this particular change happened.

https://mail.python.org/pipermail/python-ideas/2009-April/003897.html

;-) ;-)

André Roberge
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Steven D'Aprano
On Fri, Mar 15, 2019 at 12:20:21PM +0100, Antoine Pitrou wrote:

> Agreed with this.  What is so useful exactly in this new dict operator
> that it hasn't been implemented, say, 20 years ago?

One could say the same thing about every new feature. Since Python 1.5
was so perfect, why add Unicode, decorators, matrix multiplication, 
async, descriptors, Decimal, iterators, ... 

Matrix multiplication is a perfect example: adding the @ operator could 
have been done in Python 0.1 if anyone had thought of it, but it took 15 
years of numerical folk "whinging" about the lack until it happened:

https://mail.python.org/pipermail/python-ideas/2014-March/027053.html

In some ways, it is often easier to get community buy-in for *big* 
changes, provided they are backwards compatible. With a big change, 
people often either want it, or don't care one way or another.

(Sometimes because the big change is too big or complicated or difficult 
for them to understand -- I feel that way about async. Some day I'll 
deal with it, but right now it's so far down my list of priorities that 
I have no opinion on anything to do with async.)

But *little* changes are easy enough for everyone to understand, and so 
they trigger the impulse to bike-shed. Everyone has an opinion on 
whether or not dicts should support an update operator, and whether to 
spell it + or | or <- or << or something else.

Or the infamous := operator, which ultimately is a useful but minor 
syntactic and semantic change but generated a huge amount of debate, 
argument and negativity. A far smaller change to the language than 
adding type hinting, but it generated far more argument.

I still remember being told in no uncertain terms by the core devs that 
adding a clear() method to lists was a waste of time because there was 
already a perfectly good way to spell it with slicing. And then ABCs 
came along and now lists have a clear method. So opinions change too.

Things happen when they happen, because if they had happened earlier we 
wouldn't still be arguing about them.



> I rarely find
> myself merging dicts and, when I do, calling dict.update() is entirely
> acceptable

The code we write is shaped by the operators and methods that
exist. You use dict.update() because *it exists* so when you want a new 
dict merged with another, you write the code that is possible today:

new = spam.copy()
new.update(eggs)
process(new)

and you are content because you "rarely find myself merging dicts".

But perhaps those who *frequently* merge dicts have a different option, 
and would prefer to write one line rather than three and avoid naming 
something that doesn't need a name:

process(spam + eggs)  # or spam|eggs if you prefer


> (I think the "{**d}" notation was already a mistake, making
> a perfectly readable operation more cryptic simply for the sake of
> saving a few keystrokes).

I don't know if it was a mistake, but disatisfaction with its lack of 
readability and discoverability is one of the motivations of this PEP.


[...]
> Besides, if I have two dicts with e.g. lists as values, I *really*
> dislike the fact that the + operator will clobber the values rather than
> concatenate them.  It's a recipe for confusion.

Are you confused that the update method clobbers list values rather than 
concatenate them? I doubt that you are.

So why would it be confusing to say that + does a copy-and-update?

(In any case, popular opinion may be shifting towards preferring the | 
operator over + so perhaps confusion over concatenation may not be an 
issue in the future.)



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Antoine Pitrou
On Thu, 7 Mar 2019 10:58:02 +1100
Chris Angelico  wrote:
> 
> Lots of words that basically say: Stuff wouldn't be perfectly pure.

Chris, please learn to think twice before contributing what is
essentially a trivialization of someone else's arguments.  You're not
doing anything useful here, and are just sounding like an asshole who
wants to shut people up.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Antoine Pitrou
On Mon, 4 Mar 2019 15:57:38 -0800
Guido van Rossum  wrote:
> 
> > Those two points make me uncomfortable with "+=" strictly behaving
> > like ".update()".
> 
> And yet that's how it works for lists. (Note that dict.update() still has
> capabilities beyond +=, since you can also invoke it with keyword args.)

Yeah, well I do think "+=" for lists was a mistake.  I *still* have
trouble remembering the exact difference between "list +=" and
"list.extend" (yes, there is one: one accepts more types than the
other... which one it is, and why, I never remember; and, of course,
there might be the obscure performance difference because of
CPython's execution details).

I should not have to remember whether I want to use "list +=" or
"list.extend" every time I need to extend a list.  There is a virtue to

"""There should be one-- and preferably only one --obvious way to do
it"""

and we shouldn't break it more than we already did.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Antoine Pitrou
On Mon, 4 Mar 2019 16:02:06 +0100
Stefan Behnel  wrote:
> INADA Naoki schrieb am 04.03.19 um 11:15:
> > Why statement is not enough?  
> 
> I'm not sure I understand why you're asking this, but a statement is "not
> enough" because it's a statement and not an expression.

This is an argument for Perl 6, not for Python.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-15 Thread Antoine Pitrou
On Wed, 6 Mar 2019 00:46:57 +
Josh Rosenberg

wrote:
> 
> Overloading + lacks the clear descriptive aspect of update that describes
> the goal of the operation, and contradicts conventions (in Python and
> elsewhere) about how + works (addition or concatenation, and a lot of
> people don't even like it doing the latter, though I'm not that pedantic).
> 
> A couple "rules" from C++ on overloading are "*Whenever the meaning of an
> operator is not obviously clear and undisputed, it should not be
> overloaded.* *Instead, provide a function with a well-chosen name.*"
> and "*Always
> stick to the operator’s well-known semantics".* (Source:
> https://stackoverflow.com/a/4421708/364696 , though the principle is
> restated in many other places).

Agreed with this.  What is so useful exactly in this new dict operator
that it hasn't been implemented, say, 20 years ago?  I rarely find
myself merging dicts and, when I do, calling dict.update() is entirely
acceptable (I think the "{**d}" notation was already a mistake, making
a perfectly readable operation more cryptic simply for the sake of
saving a few keystrokes).

Built-in operations should be added with regard to actual user needs
(such as: a first-class notation for matrix multiplication, making
formulas easier to read and understand), not a mere "hmm this might
sometimes be useful".


Besides, if I have two dicts with e.g. lists as values, I *really*
dislike the fact that the + operator will clobber the values rather than
concatenate them.  It's a recipe for confusion.

Regards

Antoine.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-12 Thread Chris Barker via Python-ideas
Just in case I'm not the only one that had a hard time finding the latest
version of this PEP, here it is in the PEPS Repo:

https://github.com/python/peps/blob/master/pep-0584.rst

-CHB



-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-09 Thread Steven D'Aprano
On Sat, Mar 09, 2019 at 11:39:39AM -0800, Stephan Hoyer wrote:
> Would __iadd__ and __isub__ be added to collections.abc.MutableMapping?

No, that will not be part of the PEP. The proposal is only to change 
dict itself. If people want to add this to MutableMapping, that could be 
considered seperately.



-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-09 Thread Stephan Hoyer
Would __iadd__ and __isub__ be added to collections.abc.MutableMapping?

This would be consistent with other infix operations on mutable ABCs, but
could potentially break backwards compatibility for anyone who has defined
a MutableMapping subclass that implements __add__ but not __iadd__.
On Sat, Mar 9, 2019 at 8:55 AM Steven D'Aprano  wrote:

> Thanks to everyone who has contributed to the discussion, I have been
> reading all the comments even if I haven't responded.
>
> I'm currently working on an update to the PEP which will, I hope,
> improve some of the failings of the current draft.
>
>
> --
> Steven
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-09 Thread Steven D'Aprano
Thanks to everyone who has contributed to the discussion, I have been 
reading all the comments even if I haven't responded.

I'm currently working on an update to the PEP which will, I hope, 
improve some of the failings of the current draft.


-- 
Steven
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread James Edwards
On Fri, Mar 8, 2019 at 11:25 AM João Matos  wrote:

> I've just read your PEP 585 draft and have some questions.
> When you say
> "
>
> Like the merge operator and list concatenation, the difference operator
> requires both operands to be dicts, while the augmented version allows any
> iterable of keys.
>
> >>> d - {'spam', 'parrot'}
> Traceback (most recent call last):
>   ...
> TypeError: cannot take the difference of dict and set
>
> >>> d -= {'spam', 'parrot'}
> >>> print(d)
> {'eggs': 2, 'cheese': 'cheddar'}
>
> >>> d -= [('spam', 999)]
> >>> print(d)
> {'spam': 999, 'eggs': 2, 'cheese': 'cheddar', 'aardvark': 'Ethel'}
>
>
> "
>
> The option d -= {'spam', 'parrot'} where parrot does not exist in the d
> dict, will raise an exception (eg. KeyNotFound) or be silent?
>
> The option d -= [('spam', 999)] should remove the pair from the dict,
> correct? But the print that follows still shows it there. It's a mistake or
> am I missing something?
>

My understanding is that:

 - (Q1) Attempting to discard a key not in the target of the augmented
assignment would *not *raise a KeyError (or any Exception for that
matter).  This is analogous to how the - operator works on sets and is
consistent with the pure python implementation towards the bottom of the
PEP.
 - (Q2) This one got me as well while implementing the proposal in cpython,
but there is a difference in what "part" of the RHS the operators "care
about" if the RHS isn't a dict.  The += operator expects 2-tuples and will
treat them as (key, value) pairs.  The -= operator doesn't attempt to
unpack the RHS's elements as += does and expects keys.  So d -= [('spam',
999)] treated the tuple as a *key *and attempted to discard it.

IOW,

d = {
'spam': 999,
('spam', 999): True
}
d -= [('spam', 999)]

Would discard the *key* ('spam', 999) and corresponding value True.

Which highlights a possibly surprising incongruence between the operators:

d = {}
update = [(1,1), (2,2), (3,3)]
d += update
d -= update
assert d == {}  # will raise, as d still has 3 items

Similarly,

d = {}
update = {1:1, 2:2, 3:3}
d += update.items()
d -= update.items()
assert d == {}  # will raise, for the same reason
d -= update.keys()
assert d == {}  # would pass without issue

That being said I (personally) wouldn't consider it a deal-breaker and
still would very much appreciate of the added functionality (regardless of
the choice of operator).

- Jim
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread Greg Ewing

Guido van Rossum wrote:
I guess everybody's high school math(s) class was different. I don't 
ever recall seeing + and * for boolean OR/AND; we used ∧ and ∨.


Boolean algebra was only touched on briefly in my high school
years. I can't remember exactly what notation was used, but it
definitely wasn't ∧ and ∨ -- I didn't encounter those until
much later.

However, I've definitely seen texts on boolean alegbra in
relation to logic circuits that write 'A and B' as 'AB',
and 'A or B' as 'A + B'. (And also use an overbar for
negation instead of the mathematical ¬).

Maybe it depends on whether you're a mathematician or an
engineer? The multiplication-addition notation seems a lot
more readable when you have a complicated boolean expression,
so I can imagine it being favoured by pragmatic engineering
type people.

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread Guido van Rossum
On Fri, Mar 8, 2019 at 3:33 PM Greg Ewing 
wrote:

> Guido van Rossum wrote:
> > I guess this explains the behavior of removing results <= 0; it makes
> > sense as multiset subtraction, since in a multiset a negative count
> > makes little sense. (Though the name Counter certainly doesn't seem to
> > imply multiset.)
>
> It doesn't even behave consistently as a multiset, since c[k] -= n
> is happy to let the value go negative.
>
> > For sets,
> > union and intersection are distributive over each other.
>
> > Note that this is *not* the case for + and * when used with
> > (mathematical) numbers... So in a sense, SETL (which uses + and *
>  > for union and intersection got the operators wrong.
>
> But in another sense, it didn't. In Boolean algebra, "and" and "or"
> (which also distribute over each other) are often written using the
> same notations as multiplication and addition. There's no rule in
> mathematics saying that these notations must be distributive in one
> direction but not the other.
>

I guess everybody's high school math(s) class was different. I don't ever
recall seeing + and * for boolean OR/AND; we used ∧ and ∨.

I learned | and & for set operations only after I learned programming; I
think it was in PL/1. But of course it stuck because of C bitwise operators
(which are also boolean OR/AND and set operations).

This table suggests there's a lot of variety in how these operators are
spelled:
https://en.wikipedia.org/wiki/List_of_logic_symbols

-- 
--Guido van Rossum (python.org/~guido)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread Greg Ewing

Guido van Rossum wrote:
I guess this explains the behavior of removing results <= 0; it makes 
sense as multiset subtraction, since in a multiset a negative count 
makes little sense. (Though the name Counter certainly doesn't seem to 
imply multiset.)


It doesn't even behave consistently as a multiset, since c[k] -= n
is happy to let the value go negative.

For sets, 
union and intersection are distributive over each other.


Note that this is *not* the case for + and * when used with 
(mathematical) numbers... So in a sense, SETL (which uses + and *

> for union and intersection got the operators wrong.

But in another sense, it didn't. In Boolean algebra, "and" and "or"
(which also distribute over each other) are often written using the
same notations as multiplication and addition. There's no rule in
mathematics saying that these notations must be distributive in one
direction but not the other.

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread MRAB

On 2019-03-08 16:55, Guido van Rossum wrote:
[snip]
If we were to use "|" and "&" for dict "union" and "intersection", the 
mutual distributive properties will hold.


Since "|" (especially "|=") *is* suitable for "update", I think we
should reserve "+" for some future commutative extension.


One argument is that sets have an update() method aliased to "|=", so 
this makes it more reasonable to do the same for dicts, which also have 
a. update() method, with similar behavior (not surprising, since sets 
were modeled after dicts).



[snip]
One way to think of it is that a dict is like a set, except that each of 
its members has an additional associated value.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread Guido van Rossum
On Thu, Mar 7, 2019 at 9:12 PM Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp> wrote:

> Ka-Ping Yee writes:
>  > On Wed, Mar 6, 2019 at 4:01 PM Chris Angelico  wrote:
>
>  > > But adding dictionaries is fundamentally *useful*. It is expressive.
>  >
>  > It is useful.  It's just that + is the wrong name.
>
> First, let me say that I prefer ?!'s position here, so my bias is made
> apparent.  I'm also aware that I have biases so I'm sympathetic to
> those who take a different position.
>

TBH, I am warming up to "|" as well.


> Rather than say it's "wrong", let me instead point out that I think
> it's pragmatically troublesome to use "+".  I can think of at least
> four interpretations of "d1 + d2"
>
> 1.  update
> 2.  multiset (~= Collections.Counter addition)
>

I guess this explains the behavior of removing results <= 0; it makes sense
as multiset subtraction, since in a multiset a negative count makes little
sense. (Though the name Counter certainly doesn't seem to imply multiset.)


> 3.  addition of functions into the same vector space (actually, a
> semigroup will do ;-), and this is the implementation of
> Collections.Counter
> 4.  "fiberwise" set addition (ie, of functions into relations)
>
> and I'm very jet-lagged so I may be missing some.
>
> There's also the fact that the operations denoted by "|" and "||" are
> often implemented as "short-circuiting", and therefore not
> commutative, while "+" usually is (and that's reinforced for
> mathematicians who are trained to think of "+" as the operator for
> Abelian groups, while "*" is a (possibly) non-commutative operator.  I
> know commutativity of "+" has been mentioned before, but the
> non-commutativity of "|" -- and so unsuitability for many kinds of
> dict combination -- hasn't been emphasized before IIRC.
>

I've never heard of single "|" being short-circuiting. ("||" of course is
infamous for being that in C and most languages derived from it.)

And "+" is of course used for many non-commutative operations in Python
(e.g. adding two lists/strings/tuples together). It is only *associative*,
a weaker requirement that just says (A + B) + C == A + (B + C). (This is
why we write A + B + C, since the grouping doesn't matter for the result.)

Anyway, while we're discussing mathematical properties, and since SETL was
briefly mentioned, I found an interesting thing in math. For sets, union
and intersection are distributive over each other. I can't type the
operators we learned in high school, so I'll use Python's set operations.
We find that A | (B & C) == (A | B) & (A | C). We also find that A & (B |
C) == (A & B) | (A & C).

Note that this is *not* the case for + and * when used with (mathematical)
numbers: * distributes over +: a * (b + c) == (a * b) + (a * c), but + does
not distribute over *: a + (b * c) != (a + b) * (a + c). So in a sense,
SETL (which uses + and * for union and intersection) got the operators
wrong.

Note that in Python, + and * for sequences are not distributive this way,
since (A + B) * n is not the same as (A * n) + (B * n). OTOH A * (n + m) ==
A * n + A * m. (Assuming A and B are sequences of the same type, and n and
m are positive integers.)

If we were to use "|" and "&" for dict "union" and "intersection", the
mutual distributive properties will hold.


> Since "|" (especially "|=") *is* suitable for "update", I think we
> should reserve "+" for some future commutative extension.
>

One argument is that sets have an update() method aliased to "|=", so this
makes it more reasonable to do the same for dicts, which also have a.
update() method, with similar behavior (not surprising, since sets were
modeled after dicts).


> In the spirit of full disclosure:
> Of these, 2 is already implemented and widely used, so we don't need
> to use dict.__add__ for that.  I've never seen 4 in the mathematical
> literature (union of relations is not the same thing).  3, however, is
> very common both for mappings with small domain and sparse
> representation of mappings with a default value (possibly computed
> then cached), and "|" is not suitable for expressing that sort of
> addition (I'm willing to say it's "wrong" :-).
>

-- 
--Guido van Rossum (python.org/~guido)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread João Matos

  
  
Hello,

I've just read your PEP 585 draft and have some questions.
When you say
"
Like the merge operator and list concatenation, the difference
  operator requires both operands to be dicts, while the augmented
  version allows any iterable of keys.

  >>> d - {'spam', 'parrot'}
Traceback (most recent call last):
  ...
TypeError: cannot take the difference of dict and set

  >>> d -= {'spam', 'parrot'}
>>> print(d)
{'eggs': 2, 'cheese': 'cheddar'}

  >>> d -= [('spam', 999)]
>>> print(d)
{'spam': 999, 'eggs': 2, 'cheese': 'cheddar', 'aardvark': 'Ethel'}
 


"

The option d -= {'spam', 'parrot'} where parrot does not exist in
the d dict, will raise an exception (eg. KeyNotFound) or be silent?

The option d -= [('spam', 999)] should remove the pair from the
dict, correct? But the print that follows still shows it there. It's
a mistake or am I missing something?


Best regards,

João Matos


  




smime.p7s
Description: S/MIME Cryptographic Signature
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-07 Thread Stephen J. Turnbull
Ka-Ping Yee writes:
 > On Wed, Mar 6, 2019 at 4:01 PM Chris Angelico  wrote:

 > > But adding dictionaries is fundamentally *useful*. It is expressive.
 > 
 > It is useful.  It's just that + is the wrong name.

First, let me say that I prefer ?!'s position here, so my bias is made
apparent.  I'm also aware that I have biases so I'm sympathetic to
those who take a different position.

Rather than say it's "wrong", let me instead point out that I think
it's pragmatically troublesome to use "+".  I can think of at least
four interpretations of "d1 + d2"

1.  update
2.  multiset (~= Collections.Counter addition)
3.  addition of functions into the same vector space (actually, a
semigroup will do ;-), and this is the implementation of
Collections.Counter
4.  "fiberwise" set addition (ie, of functions into relations)

and I'm very jet-lagged so I may be missing some.

There's also the fact that the operations denoted by "|" and "||" are
often implemented as "short-circuiting", and therefore not
commutative, while "+" usually is (and that's reinforced for
mathematicians who are trained to think of "+" as the operator for
Abelian groups, while "*" is a (possibly) non-commutative operator.  I
know commutativity of "+" has been mentioned before, but the
non-commutativity of "|" -- and so unsuitability for many kinds of
dict combination -- hasn't been emphasized before IIRC.

Since "|" (especially "|=") *is* suitable for "update", I think we
should reserve "+" for some future commutative extension.

In the spirit of full disclosure:
Of these, 2 is already implemented and widely used, so we don't need
to use dict.__add__ for that.  I've never seen 4 in the mathematical
literature (union of relations is not the same thing).  3, however, is
very common both for mappings with small domain and sparse
representation of mappings with a default value (possibly computed
then cached), and "|" is not suitable for expressing that sort of
addition (I'm willing to say it's "wrong" :-).

Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-07 Thread Stephen J. Turnbull
Ka-Ping Yee writes:
 > On Wed, Mar 6, 2019 at 4:01 PM Chris Angelico  wrote:

 > > But adding dictionaries is fundamentally *useful*. It is expressive.
 > 
 > It is useful.  It's just that + is the wrong name.

First, let me say that I prefer ?!'s position here, so my bias is made
apparent.  I'm also aware that I have biases so I'm sympathetic to
those who take a different position.

Rather than say it's "wrong", let me instead point out that I think
it's pragmatically troublesome to use "+".  I can think of at least
four interpretations of "d1 + d2"

1.  update
2.  multiset (~= Collections.Counter addition)
3.  addition of functions into the same vector space (actually, a
semigroup will do ;-), and this is the implementation of
Collections.Counter
4.  "fiberwise" addition (ie, assembling functions into relations)

and I'm very jet-lagged so I may be missing some.

Since "|" (especially "|=") *is* suitable for "update", I think we
should reserve "+" for some alternative future commutative extension,
of which there are several possible (all of 2, 3, 4 are commutative).

Again in the spirit of full disclosure, of those above, 2 is already
implemented and widely used, so we don't need to use "+" for that.
I've never seen 4 except in the mathematical literature (union of
relations is not the same thing).  3, however, is very common both for
mappings with small domain and sparse representation of mappings with
a default value (possibly computed then cached), and "|" is not
suitable for expressing that sort of addition (I'm willing to say it's
"wrong" :-).

There's also the fact that the operations denoted by "|" and "||" are
often implemented as "short-circuiting", and therefore not
commutative, while "+" usually is (and that's reinforced for
mathematicians who are trained to think of "+" as the operator for
Abelian groups, while "*" is a (possibly) non-commutative operator.  I
know commutativity of "+" has been mentioned before, but the
non-commutativity of "|" -- and so unsuitability for many kinds of
dict combination -- hasn't been emphasized before IIRC.

Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-07 Thread James Lu
Now, this belongs as a separate PEP, and I probably will write one, but I 
propose:

d1 << d2 makes a copy of d1 and merges d2 into it, and when the keys conflict, 
d2 takes priority. (Works like copy/update.)

d1 + d2 makes a new dictionary, taking keys from d1 and d2. If d1 and d2 have a 
different value for same key, a KeyError is thrown. 




___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-07 Thread Ka-Ping Yee
On Wed, Mar 6, 2019 at 4:01 PM Chris Angelico  wrote:

> On Thu, Mar 7, 2019 at 10:52 AM Josh Rosenberg
>  wrote:
> >
> > Allowing dicts to get involved in + means:
>
> Lots of words that basically say: Stuff wouldn't be perfectly pure.
>
> But adding dictionaries is fundamentally *useful*. It is expressive.
>

It is useful.  It's just that + is the wrong name.

Filtering and subtracting from dictionaries are also useful!  Those are
operations we do all the time.  It would be useful if & and - did these
things too—and if we have & and -, it's going to be even more obvious that
the merge operator should have been |.


Josh Rosenberg  wrote:

> If we were inventing programming languages in a vacuum, you could say +
> can mean "arbitrary combination operator" and it would be fine. But we're
> not in a vacuum; every major language that uses + with general purpose
> containers uses it to mean element-wise addition or concatenation, not just
> "merge".


If we were inventing Python from scratch, we could have decided that we
always use "+" to combine collections.  Sets would combine with + and then
it would make sense that dictionaries also combine with + .

But that is not Python.  Lists combine with + and sets combine with |.
Why?  Because lists add (put both collections together and keep
everything), but sets merge (put both collections together and keep some).

So, Python already has a merge operator.  The merge operator is "|".

For lists, += is shorthand for list.extend().
For sets, |= is shorthand for set.update().

Is dictionary merge more like extend() or more like update()?  Python
already took a position on that when it was decided to name the dictionary
method update().  That ship sailed a long time ago.


—Ping
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Chris Angelico
On Thu, Mar 7, 2019 at 10:52 AM Josh Rosenberg
 wrote:
> The closest I can come to a thorough definition of what + does in Python (and 
> most languages) right now is that:
>
> 1. Returns a new thing of the same type (or a shared coerced type for number 
> weirdness)
> 2. That combines the information of the input operands
> 3. Is associative ((a + b) + c produces the same thing as a + (b + c)) 
> (modulo floating point weirdness)
> 4. Is "reversible": Knowing the end result and *one* of the inputs is 
> sufficient to determine the value of the other input; that is, for c = a + b, 
> knowing any two of a, b and c allows you to determine a single unambiguous 
> value for the remaining value (numeric coercion and floating point weirdness 
> make this not 100%, but you can at least know a value equal to other value; 
> e.g. for c = a + b, knowing c is 5.0 and a is 1.0 is sufficient to say that b 
> is equal to 4, even if it's not necessarily an int or float). For numbers, 
> reversal is done with -; for sequences, it's done by slicing c using the 
> length of a or b to "subtract" the elements that came from a/b.
> 5. (Actual addition only) Is commutative (modulo floating point weirdness); a 
> + b == b + a
> 6. (Concatenation only) Is order preserving (really a natural consequence of 
> #4, but a property that people expect)
>
> Allowing dicts to get involved in + means:
>
> 1. Fewer consistent rules apply to +;
> 2. The particular idiosyncrasies of Python dict ordering and "which value 
> wins" rules are now tied to +. for concatenation, there is only one set of 
> possible rules AFAICT so every language naturally agrees on behavior, but 
> dict merging obviously has many possible rules that would be unlikely to 
> match the exact rules of any other language except by coincidence). a winning 
> on order and b winning on value is a historical artifact of how Python's dict 
> developed; I doubt any other language would intentionally choose to split 
> responsibility like that if they weren't handcuffed by history.
>
> Again, there's nothing wrong with making dict merges easier. But it shouldn't 
> be done by (further) abusing +.

Lots of words that basically say: Stuff wouldn't be perfectly pure.

But adding dictionaries is fundamentally *useful*. It is expressive.
It will, in pretty much all situations, do exactly what someone would
expect, based on knowledge of how Python works in other areas. The
semantics for edge cases have to be clearly defined, but they'll only
come into play on rare occasions; most of the time, for instance, we
don't have to worry about identity vs equality in dictionary keys. If
you tell people "adding two dictionaries combines them, with the right
operand winning collisions", it won't matter that this isn't how lists
or floats work; it'll be incredibly useful as it is.

Practicality. Let's have some.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Josh Rosenberg
On Wed, Mar 6, 2019 at 10:31 PM Greg Ewing 
wrote:

>
> You might as well say that using the + operator on vectors is
> nonsense, because len(v1 + v2) is not in general equal to
> len(v1) + len(v2).
>
> Yet mathematicians are quite happy to talk about "addition"
> of vectors.
>
>
Vectors addition is *actual* addition, not concatenation. You're so busy
loosening the definition of + as relates to , to make it make sense for
dicts that you've forgotten that + is, first and foremost, about addition
in the mathematical sense, where vector addition is just one type of
addition. Concatenation is already a minor abuse of +, but one commonly
accepted by programmers, thanks to it having some similarities to addition
and a single, unambiguous set of semantics to avoid confusion.

You're defending + on dicts because vector addition isn't concatenation
already, which only shows how muddled things get when you try to use + to
mean multiple concepts that are at best loosely related.

The closest I can come to a thorough definition of what + does in Python
(and most languages) right now is that:

1. Returns a new thing of the same type (or a shared coerced type for
number weirdness)
2. That combines the information of the input operands
3. Is associative ((a + b) + c produces the same thing as a + (b + c))
(modulo floating point weirdness)
4. Is "reversible": Knowing the end result and *one* of the inputs is
sufficient to determine the value of the other input; that is, for c = a +
b, knowing any two of a, b and c allows you to determine a single
unambiguous value for the remaining value (numeric coercion and floating
point weirdness make this not 100%, but you can at least know a value equal
to other value; e.g. for c = a + b, knowing c is 5.0 and a is 1.0 is
sufficient to say that b is equal to 4, even if it's not necessarily an int
or float). For numbers, reversal is done with -; for sequences, it's done
by slicing c using the length of a or b to "subtract" the elements that
came from a/b.
5. (Actual addition only) Is commutative (modulo floating point weirdness);
a + b == b + a
6. (Concatenation only) Is order preserving (really a natural consequence
of #4, but a property that people expect)

Note that these rules are consistent across most major languages that allow
+ to mean combine collections (the few that disagree, like Pascal, don't
support | as a union operator).

Concatenation is missing element #5, but otherwise aligns with actual
addition. dict merges (and set unions for that matter) violate #4 and #6;
for c = a + b, knowing c and either a or b still leaves a literally
infinite set of possible inputs for the other input (it's not infinite for
sets, where the options would be a subset of the result, but for dicts,
there would be no such limitation; keys from b could exist with any
possible value in a). dicts order preserving aspect *almost* satisfies #6,
but not quite (if 'x' comes after 'y' in b, there is no guarantee that it
will do so in c, because a gets first say on ordering, and b gets the final
word on value).

Allowing dicts to get involved in + means:

1. Fewer consistent rules apply to +;
2. The particular idiosyncrasies of Python dict ordering and "which value
wins" rules are now tied to +. for concatenation, there is only one set of
possible rules AFAICT so every language naturally agrees on behavior, but
dict merging obviously has many possible rules that would be unlikely to
match the exact rules of any other language except by coincidence). a
winning on order and b winning on value is a historical artifact of how
Python's dict developed; I doubt any other language would intentionally
choose to split responsibility like that if they weren't handcuffed by
history.

Again, there's nothing wrong with making dict merges easier. But it
shouldn't be done by (further) abusing +.

-Josh Rosenberg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Greg Ewing

Ka-Ping Yee wrote:
len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the 
+ operator is nonsense.


You might as well say that using the + operator on vectors is
nonsense, because len(v1 + v2) is not in general equal to
len(v1) + len(v2).

Yet mathematicians are quite happy to talk about "addition"
of vectors.

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Michael Lee
>
> If we use this "literally concat" metaphor, I still think set should have
> `+` as alias to `|` for consistency.
>

I agree.

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

I suppose that's true, fair point.

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.

Maybe that cost is worth it. I'm personally not convinced, but I do think
it should be taken into account..

Hmm.  The PEP proposed dict - dict, which is similar to set - set
> (difference).
>

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).

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.

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.

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.

-- Michael







On Wed, Mar 6, 2019 at 8:29 AM Inada Naoki  wrote:

> On Wed, Mar 6, 2019 at 10:59 PM Michael Lee 
> wrote:
>
> >
> > I think the behavior proposed in the PEP makes sense whether you think
> of "+" as meaning "concatenation" or "merging".
> >
> > 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.
> >
>
> Nice explanation.  You reduced my opposite to `+` by "literally concat".
> Better example, {"a": 1, "b": 2} + {"c": 4, "b": 3} == {"a": 1, "b":
> 2, "c": 4, "b": 3} == {"a": 1, "b": 3, "c": 4}
>
> On the other hand, union of set is also "literally concat".  If we use
> this "literally concat" metaphor,
> I still think set should have `+` as alias to `|` for consistency.
>
> >
> > 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)".
> >
>
> I think both rule are "rather a coincidence than a conscious decision".
>
> I think "|" keeps commutativity only because it's minor than `+`.  Easy
> operator
> is abused easily more than minor operator.
>
> And I think every "coincidence" rules are important.  They makes
> understanding Python easy.
> Every people "discover" rules and consistency while learning language.
>
> This is a matter of balance.  There are no right answer.  Someone
> *feel* rule A is important than B.
> Someone feel opposite.
>
>
> > 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.
>
> Hmm.  The PEP proposed dict - dict, which is similar to set - set
> (difference).
> To me, {"a": 1, "b": 2} - {"b": 3} = {"a": 1} is confusing than {"a":
> 1, "b": 2} - {"b"} = {"a": 1}.
>
> So I think borrow some semantics from set is good idea.
> Both of `dict - set` and `dict & set` makes sense to me.
>
> * `dict - set` can be used to remove private keys by "blacklist".
> * `dict & set` can be used to choose public keys by "whiltelist".
>
> --
> Inada Naoki  
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Jonathan Fine
I wrote:

> I wonder, is this behaviour of {'a': 0, 'a': 1} documented (or tested)
> anywhere?

I've answered my own question here:
[Python-ideas] dict literal allows duplicate keys
https://mail.python.org/pipermail/python-ideas/2019-March/055717.html

Finally, Christopher Barker wrote:
> Yes, and had already been brought up in this thread ( I think by Guido). 
> (Maybe not well documented, but certainly well understood and deliberate)

Thank you for this, Christopher.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Inada Naoki
On Wed, Mar 6, 2019 at 10:59 PM Michael Lee  wrote:

>
> I think the behavior proposed in the PEP makes sense whether you think of "+" 
> as meaning "concatenation" or "merging".
>
> 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.
>

Nice explanation.  You reduced my opposite to `+` by "literally concat".
Better example, {"a": 1, "b": 2} + {"c": 4, "b": 3} == {"a": 1, "b":
2, "c": 4, "b": 3} == {"a": 1, "b": 3, "c": 4}

On the other hand, union of set is also "literally concat".  If we use
this "literally concat" metaphor,
I still think set should have `+` as alias to `|` for consistency.

>
> 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)".
>

I think both rule are "rather a coincidence than a conscious decision".

I think "|" keeps commutativity only because it's minor than `+`.  Easy operator
is abused easily more than minor operator.

And I think every "coincidence" rules are important.  They makes
understanding Python easy.
Every people "discover" rules and consistency while learning language.

This is a matter of balance.  There are no right answer.  Someone
*feel* rule A is important than B.
Someone feel opposite.


> 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.

Hmm.  The PEP proposed dict - dict, which is similar to set - set (difference).
To me, {"a": 1, "b": 2} - {"b": 3} = {"a": 1} is confusing than {"a":
1, "b": 2} - {"b"} = {"a": 1}.

So I think borrow some semantics from set is good idea.
Both of `dict - set` and `dict & set` makes sense to me.

* `dict - set` can be used to remove private keys by "blacklist".
* `dict & set` can be used to choose public keys by "whiltelist".

-- 
Inada Naoki  
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Jonathan Fine
Michael Lee wrote:

> 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.

> But of course, you can't have duplicate keys in Python. So, you would either 
> recall or look up how duplicate keys are handled when constructing a dict and 
> learn that the rule is that the right-most key wins. So the natural 
> conclusion is that "+" would follow this existing rule -- and you end up with 
> exactly the behavior described in the PEP.

This is a nice argument. And well presented. And it gave me surprise,
that taught me something. Here goes:

>>> {'a': 0}
{'a': 0}
>>> {'a': 0, 'a': 0}
{'a': 0}
>>> {'a': 0, 'a': 1}
{'a': 1}
>>> {'a': 1, 'a': 0}
{'a': 0}

This surprised me quite a bit. I was expecting to get an exception. However

>>> dict(a=0)
{'a': 0}
>>> dict(a=0, a=0)
SyntaxError: keyword argument repeated

does give an exception.

I wonder, is this behaviour of {'a': 0, 'a': 1} documented (or tested)
anywhere? I didn't find it in these URLs:
https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
https://docs.python.org/3/tutorial/datastructures.html#dictionaries

I think this behaviour might give rise to gotchas. For example, if we
define inverse_f by
>>> inverse_f = { f(a): a, f(b): b }
then is the next statement always true (assuming a <> b)?
>>> inverse_f[ f(a) ] == a

Well, it's not true with these values
>>> a, b = 1, 2
>>> def f(n): pass # There's a bug here, f(n) should be a bijection.

A quick check that len(inverse) == 2 would provide a sanity check. Or
perhaps better, len(inverse_f) == len(set(a, b)). (I don't have an
example of this bug appearing 'in the wild'.)

Once again, I thank Michael for his nice, instructive and
well-presented example.
-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Chris Angelico
On Thu, Mar 7, 2019 at 12:59 AM Michael Lee  wrote:
> 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.
>
> But of course, you can't have duplicate keys in Python. So, you would either 
> recall or look up how duplicate keys are handled when constructing a dict and 
> learn that the rule is that the right-most key wins. So the natural 
> conclusion is that "+" would follow this existing rule -- and you end up with 
> exactly the behavior described in the PEP.
>

Which, by the way, is also consistent with assignment:

d = {}; d["a"] = 1; d["b"] = 2; d["c"] = 3; d["b"] = 4

Rightmost one wins. It's the most logical behaviour.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Michael Lee
>
> I strongly agree with Ka-Ping. '+' is intuitively concatenation not
> merging. The behavior is overwhelmingly more similar to the '|' operator in
> sets (whether or not a user happens to know the historical implementation
> overlap).


I think the behavior proposed in the PEP makes sense whether you think of
"+" as meaning "concatenation" or "merging".

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.

But of course, you can't have duplicate keys in Python. So, you would
either recall or look up how duplicate keys are handled when constructing a
dict and learn that the rule is that the right-most key wins. So the
natural conclusion is that "+" would follow this existing rule -- and you
end up with exactly the behavior described in the PEP.

This also makes explaining the behavior of "d1 + d2" slightly easier than
explaining "d1 | d2". For the former, you can just say "d1 + d2 means we
concat the two dicts together" and stop there. You almost don't need to
explain the merging/right-most key wins behavior at all, since that
behavior is the only one consistent with the existing language rules.

In contrast, you *would* need to explain this with "d1 | d2": I would
mentally translate this expression to mean "take the union of these two
dicts" and there's no real way to deduce which key-value pair ends up in
the final dict given that framing. Why is it that key-value pairs in d2 win
over pairs in d1 here? That choice seems pretty arbitrary when you think of
this operation in terms of unions, rather than either concat or merge.

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)".

Personally, I don't really have a strong opinion on this PEP, or the other
one I've seen proposed where we add a "d1.merge(d2, d3, ...)". 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.

-- Michael



On Wed, Mar 6, 2019 at 4:53 AM David Mertz  wrote:

> I strongly agree with Ka-Ping. '+' is intuitively concatenation not
> merging. The behavior is overwhelmingly more similar to the '|' operator in
> sets (whether or not a user happens to know the historical implementation
> overlap).
>
> I think growing the full collection of set operations world be a pleasant
> addition to dicts. I think shoe-horning in plus would always be jarring to
> me.
>
> On Wed, Mar 6, 2019, 5:30 AM Ka-Ping Yee  wrote:
>
>> len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the +
>> operator is nonsense.
>>
>> len(dict1 + dict2) cannot even be computed by any expression
>> involving +.  Using len() to test the semantics of the operation is not
>> arbitrary; the fact that the sizes do not add is a defining quality of a
>> merge.  This is a merge, not an addition.  The proper analogy is to sets,
>> not lists.
>>
>> The operators should be |, &, and -, exactly as for sets, and the
>> behaviour defined with just three rules:
>>
>> 1. The keys of dict1 [op] dict2 are the elements of dict1.keys() [op]
>> dict2.keys().
>>
>> 2. The values of dict2 take priority over the values of dict1.
>>
>> 3. When either operand is a set, it is treated as a dict whose values are
>> None.
>>
>> This yields many useful operations and, most importantly, is simple to
>> explain.  "sets and dicts can |, &, -" takes up less space in your brain
>> than "sets can |, &, - but dicts can only + and -, where dict + is like set
>> |".
>>
>> merge and update some items:
>>
>> {'a': 1, 'b': 2} | {'b': 3, 'c': 4} => {'a': 1, 'b': 3, 'c': 4}
>>
>> pick some items:
>>
>> {'a': 1, 'b': 2} & {'b': 3, 'c': 4} => {'b': 3}
>>
>> remove some items:
>>
>> {'a': 1, 'b': 2} - {'b': 3, 'c': 4} => {'a': 1}
>>
>> reset values of some keys:
>>
>> {'a': 1, 'b': 2} | {'b', 'c'} => {'a': 1, 'b': None, 'c': None}
>>
>> ensure certain keys are present:
>>
>> {'b', 'c'} | {'a': 1, 'b': 2} => {'a': 1, 'b': 2, 'c': None}
>>
>> pick some items:
>>
>> {'b', 'c'} | {'a': 1, 'b': 2} => {'b': 2}
>>
>> remove some items:
>>
>> {'a': 1, 'b': 2} - {'b', 'c'} => {'a': 1}
>>
>> On Wed, Mar 6, 2019 at 1:51 AM Rémi Lapeyre 
>> wrote:
>>
>>> Le 6 mars 2019 à 10:26:15, Brice Parent
>>> (cont...@brice.xyz(mailto:cont...@brice.xyz)) a écrit:
>>>

Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Brice Parent



Le 06/03/2019 à 13:53, Chris Angelico a écrit :

On Wed, Mar 6, 2019 at 11:18 PM Brice Parent  wrote:

The major implication to such a
modification of the Dict.update method, is that when you're using it
with keyword arguments (by opposition to passing another dict/iterable
as positional), you're making a small non-backward compatible change in
that if in some code, someone was already using the keyword that would
be chosing (here "on_collision"), their code would be broken by the new
feature.
Anyway, if
the keyword is slected wisely, the collision case will almost never
happen, and be quite easy to correct if it ever happened.

You can make it unlikely, yes, but I'd dispute "easy to correct".
Let's suppose that someone had indeed used the chosen keyword (and
remember, the more descriptive the argument name, the more likely that
it'll be useful elsewhere and therefore have a collision). How would
they discover this? If they're really lucky, there MIGHT be an
exception (if on_collision accepts only a handful of keywords, and the
collision isn't one of them), but if your new feature is sufficiently
flexible, that might not happen. There'll just be incorrect behaviour.

As APIs go, using specific keyword args at the same time as **kw is a
bit odd. Consider:

button_options.update(button_info, on_click=frobnicate, style="KDE",
on_collision="replace")

It's definitely not obvious which of those will end up in the
dictionary and which won't. Big -1 from me on that change.
That's indeed a good point. Even if the correction is quite easy to make 
in most cases. With keyword only changes:


button_options.update(dict(on_click=frobnicate, style="KDE", on_collision="replace"))  # or 
button_options.update(dict(on_collision="replace"), on_click=frobnicate, style="KDE")

In the exact case you proposed, it could become a 2-liners:

button_options.update(button_info)
button_options.update(dict(on_click=frobnicate, style="KDE", 
on_collision="replace"))

In my code, I would probably make it into 2 lines, to make clear that we 
have 2 levels of data merging, one that is general (the first), and one 
that is specific to this use-case (as it's hard written in the code), 
but not everyone doesn't care about the number of lines.


But for the other part of your message, I 100% agree with you. The main 
problem with such a change is not (to me) that it can break some edge 
cases, but that it would potentially break them silently. And that, I 
agree, is worth a big -1 I guess.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Chris Angelico
On Wed, Mar 6, 2019 at 11:18 PM Brice Parent  wrote:
> The major implication to such a
> modification of the Dict.update method, is that when you're using it
> with keyword arguments (by opposition to passing another dict/iterable
> as positional), you're making a small non-backward compatible change in
> that if in some code, someone was already using the keyword that would
> be chosing (here "on_collision"), their code would be broken by the new
> feature.
> Anyway, if
> the keyword is slected wisely, the collision case will almost never
> happen, and be quite easy to correct if it ever happened.

You can make it unlikely, yes, but I'd dispute "easy to correct".
Let's suppose that someone had indeed used the chosen keyword (and
remember, the more descriptive the argument name, the more likely that
it'll be useful elsewhere and therefore have a collision). How would
they discover this? If they're really lucky, there MIGHT be an
exception (if on_collision accepts only a handful of keywords, and the
collision isn't one of them), but if your new feature is sufficiently
flexible, that might not happen. There'll just be incorrect behaviour.

As APIs go, using specific keyword args at the same time as **kw is a
bit odd. Consider:

button_options.update(button_info, on_click=frobnicate, style="KDE",
on_collision="replace")

It's definitely not obvious which of those will end up in the
dictionary and which won't. Big -1 from me on that change.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Jonathan Fine
Rhodri James wrote:

> Making assumptions about length where any dictionary
> manipulations are concerned seems unwise to me

I think you're a bit hasty here. Some assumptions are sensible. Suppose

a = len(d1)
b = len(d2)
c = len(d1 + d2) # Using the suggested syntax.

Then we know
   max(a, b) <= c <= a + b

And this is, in broad terms, characteristic of merge operations.
-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Jonathan Fine
Ka-Ping Yee wrote:
>
> len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the + 
> operator is nonsense.
>
> len(dict1 + dict2) cannot even be computed by any expression involving +.  
> Using len() to test the semantics of the operation is not arbitrary; the fact 
> that the sizes do not add is a defining quality of a merge.  This is a merge, 
> not an addition.  The proper analogy is to sets, not lists.

For me, this comment is excellent. It neatly expresses the central
concern about this proposal. I think most us will agree that the
proposal is to use '+' to express a merge operation, namely update.
(There are other merge operations, when there are two values to
combine, such as taking the min or max of the two values.)

Certainly, many of the posts quite naturally use the word merge.
Indeed PEP 584 writes "This PEP suggests adding merge '+' and
difference '-' operators to the built-in dict class."

We would all agree that it would be obviously wrong to suggest adding
merge '-' and difference '+' operators. (Note: I've swapped '+' and
'-'.) And why? Because it is obviously wrong to use '-' to denote
merge, etc.

Some of us are also upset by the use of '+' to denote merge. By the
way, there is already a widespread symbol for merge. It appears on
many road signs. It looks like an upside down 'Y'. It even has merge
left and merge right versions.

Python already has operator symbols '+', '-', '*', '/' and so on. See
https://docs.python.org/3/reference/lexical_analysis.html#operators

Perhaps we should add a merge or update symbol to this list, so that
we don't overload to breaking point the humble '+' operator. Although
that would make Python a bit more like APL.

By the way, Pandas already has a merge operation, called merge, that
takes many parameters. I've only glanced at it.
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Josh Rosenberg
On Wed, Mar 6, 2019 at 11:52 AM Rhodri James  wrote:

> On 06/03/2019 10:29, Ka-Ping Yee wrote:
> > len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the +
> > operator is nonsense.
>
> I'm sorry, but you're going to have to justify why this identity is
> important.  Making assumptions about length where any dictionary
> manipulations are concerned seems unwise to me, which makes a nonsense
> of your claim that this is nonsense :-)
>

It's not "nonsense" per se. If we were inventing programming languages in a
vacuum, you could say + can mean "arbitrary combination operator" and it
would be fine. But we're not in a vacuum; every major language that uses +
with general purpose containers uses it to mean element-wise addition or
concatenation, not just "merge". Concatenation is what imposes that
identity (and all the others people are defending, like no loss of input
values); you're taking a sequence of things, and shoving another sequence
of things on the end of it, preserving order and all values.

The argument here isn't that you *can't* make + do arbitrary merges that
don't adhere to these semantics. It's that adding yet a third meaning to +
(and it is a third meaning; it has no precedent in any existing type in
Python, nor in any other major language; even in the minor languages that
allow it, they use + for sets as well, so Python using + is making Python
itself internally inconsistent with the operators used for set), for
limited benefit.

- Josh Rosenberg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Brice Parent



Le 06/03/2019 à 10:50, Rémi Lapeyre a écrit :

Le 05/03/2019 à 23:40, Greg Ewing a écrit :

Steven D'Aprano wrote:

The question is, is [recursive merge] behaviour useful enough and
common enough to be built into dict itself?

I think not. It seems like just one possible way of merging
values out of many. I think it would be better to provide
a merge function or method that lets you specify a function
for merging values.


That's what this conversation led me to. I'm not against the addition
for the most general usage (and current PEP's describes the behaviour I
would expect before reading the doc), but for all other more specific
usages, where we intend any special or not-so-common behaviour, I'd go
with modifying Dict.update like this:

foo.update(bar, on_collision=updator) # Although I'm not a fan of the
keyword I used

This won’t be possible update() already takes keyword arguments:


foo = {}
bar = {'a': 1}
foo.update(bar, on_collision=lambda e: e)
foo

{'a': 1, 'on_collision':  at 0x10b8df598>}

I don't see that as a problem at all.
Having a function's signature containing a **kwargs doesn't disable to 
have explicit keyword arguments at the same time:
`def foo(bar="baz", **kwargs):` is perfectly valid, as well as `def 
spam(ham: Dict, eggs="blah", **kwargs):`, so `update(other, 
on_collision=None, **added) is too, no? The major implication to such a 
modification of the Dict.update method, is that when you're using it 
with keyword arguments (by opposition to passing another dict/iterable 
as positional), you're making a small non-backward compatible change in 
that if in some code, someone was already using the keyword that would 
be chosing (here "on_collision"), their code would be broken by the new 
feature.
I had never tried to pass a dict and kw arguments together, as it seemed 
to me that it wasn't supported (I would even have expected an exception 
to be raised), but it's probably my level of English that isn't high 
enough to get it right, or this part of the doc that doesn't describe 
well the full possible usage of the method (see here: 
https://docs.python.org/3/library/stdtypes.html#dict.update). Anyway, if 
the keyword is slected wisely, the collision case will almost never 
happen, and be quite easy to correct if it ever happened.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Rhodri James

On 06/03/2019 10:29, Ka-Ping Yee wrote:

len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the +
operator is nonsense.


I'm sorry, but you're going to have to justify why this identity is 
important.  Making assumptions about length where any dictionary 
manipulations are concerned seems unwise to me, which makes a nonsense 
of your claim that this is nonsense :-)


--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Ka-Ping Yee
len(dict1 + dict2) does not equal len(dict1) + len(dict2), so using the +
operator is nonsense.

len(dict1 + dict2) cannot even be computed by any expression involving +.
Using len() to test the semantics of the operation is not arbitrary; the
fact that the sizes do not add is a defining quality of a merge.  This is a
merge, not an addition.  The proper analogy is to sets, not lists.

The operators should be |, &, and -, exactly as for sets, and the behaviour
defined with just three rules:

1. The keys of dict1 [op] dict2 are the elements of dict1.keys() [op]
dict2.keys().

2. The values of dict2 take priority over the values of dict1.

3. When either operand is a set, it is treated as a dict whose values are
None.

This yields many useful operations and, most importantly, is simple to
explain.  "sets and dicts can |, &, -" takes up less space in your brain
than "sets can |, &, - but dicts can only + and -, where dict + is like set
|".

merge and update some items:

{'a': 1, 'b': 2} | {'b': 3, 'c': 4} => {'a': 1, 'b': 3, 'c': 4}

pick some items:

{'a': 1, 'b': 2} & {'b': 3, 'c': 4} => {'b': 3}

remove some items:

{'a': 1, 'b': 2} - {'b': 3, 'c': 4} => {'a': 1}

reset values of some keys:

{'a': 1, 'b': 2} | {'b', 'c'} => {'a': 1, 'b': None, 'c': None}

ensure certain keys are present:

{'b', 'c'} | {'a': 1, 'b': 2} => {'a': 1, 'b': 2, 'c': None}

pick some items:

{'b', 'c'} | {'a': 1, 'b': 2} => {'b': 2}

remove some items:

{'a': 1, 'b': 2} - {'b', 'c'} => {'a': 1}

On Wed, Mar 6, 2019 at 1:51 AM Rémi Lapeyre  wrote:

> Le 6 mars 2019 à 10:26:15, Brice Parent
> (cont...@brice.xyz(mailto:cont...@brice.xyz)) a écrit:
>
> >
> > Le 05/03/2019 à 23:40, Greg Ewing a écrit :
> > > Steven D'Aprano wrote:
> > >> The question is, is [recursive merge] behaviour useful enough and
> > > > common enough to be built into dict itself?
> > >
> > > I think not. It seems like just one possible way of merging
> > > values out of many. I think it would be better to provide
> > > a merge function or method that lets you specify a function
> > > for merging values.
> > >
> > That's what this conversation led me to. I'm not against the addition
> > for the most general usage (and current PEP's describes the behaviour I
> > would expect before reading the doc), but for all other more specific
> > usages, where we intend any special or not-so-common behaviour, I'd go
> > with modifying Dict.update like this:
> >
> > foo.update(bar, on_collision=updator) # Although I'm not a fan of the
> > keyword I used
>
> Le 6 mars 2019 à 10:26:15, Brice Parent
> (cont...@brice.xyz(mailto:cont...@brice.xyz)) a écrit:
>
> >
> > Le 05/03/2019 à 23:40, Greg Ewing a écrit :
> > > Steven D'Aprano wrote:
> > >> The question is, is [recursive merge] behaviour useful enough and
> > > > common enough to be built into dict itself?
> > >
> > > I think not. It seems like just one possible way of merging
> > > values out of many. I think it would be better to provide
> > > a merge function or method that lets you specify a function
> > > for merging values.
> > >
> > That's what this conversation led me to. I'm not against the addition
> > for the most general usage (and current PEP's describes the behaviour I
> > would expect before reading the doc), but for all other more specific
> > usages, where we intend any special or not-so-common behaviour, I'd go
> > with modifying Dict.update like this:
> >
> > foo.update(bar, on_collision=updator) # Although I'm not a fan of the
> > keyword I used
>
> This won’t be possible update() already takes keyword arguments:
>
> >>> foo = {}
> >>> bar = {'a': 1}
> >>> foo.update(bar, on_collision=lambda e: e)
> >>> foo
> {'a': 1, 'on_collision':  at 0x10b8df598>}
>
> > `updator` being a simple function like this one:
> >
> > def updator(updated, updator, key) -> Any:
> > if key == "related":
> > return updated[key].update(updator[key])
> >
> > if key == "tags":
> > return updated[key] + updator[key]
> >
> > if key in ["a", "b", "c"]: # Those
> > return updated[key]
> >
> > return updator[key]
> >
> > There's nothing here that couldn't be made today by using a custom
> > update function, but leaving the burden of checking for values that are
> > in both and actually inserting the new values to Python's language, and
> > keeping on our side only the parts that are specific to our use case,
> > makes in my opinion the code more readable, with fewer possible bugs and
> > possibly better optimization.
> >
> >
> > ___
> > Python-ideas mailing list
> > Python-ideas@python.org
> > https://mail.python.org/mailman/listinfo/python-ideas
> > Code of Conduct: http://python.org/psf/codeofconduct/
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___

Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Rémi Lapeyre
Le 6 mars 2019 à 10:26:15, Brice Parent
(cont...@brice.xyz(mailto:cont...@brice.xyz)) a écrit:

>
> Le 05/03/2019 à 23:40, Greg Ewing a écrit :
> > Steven D'Aprano wrote:
> >> The question is, is [recursive merge] behaviour useful enough and
> > > common enough to be built into dict itself?
> >
> > I think not. It seems like just one possible way of merging
> > values out of many. I think it would be better to provide
> > a merge function or method that lets you specify a function
> > for merging values.
> >
> That's what this conversation led me to. I'm not against the addition
> for the most general usage (and current PEP's describes the behaviour I
> would expect before reading the doc), but for all other more specific
> usages, where we intend any special or not-so-common behaviour, I'd go
> with modifying Dict.update like this:
>
> foo.update(bar, on_collision=updator) # Although I'm not a fan of the
> keyword I used

Le 6 mars 2019 à 10:26:15, Brice Parent
(cont...@brice.xyz(mailto:cont...@brice.xyz)) a écrit:

>
> Le 05/03/2019 à 23:40, Greg Ewing a écrit :
> > Steven D'Aprano wrote:
> >> The question is, is [recursive merge] behaviour useful enough and
> > > common enough to be built into dict itself?
> >
> > I think not. It seems like just one possible way of merging
> > values out of many. I think it would be better to provide
> > a merge function or method that lets you specify a function
> > for merging values.
> >
> That's what this conversation led me to. I'm not against the addition
> for the most general usage (and current PEP's describes the behaviour I
> would expect before reading the doc), but for all other more specific
> usages, where we intend any special or not-so-common behaviour, I'd go
> with modifying Dict.update like this:
>
> foo.update(bar, on_collision=updator) # Although I'm not a fan of the
> keyword I used

This won’t be possible update() already takes keyword arguments:

>>> foo = {}
>>> bar = {'a': 1}
>>> foo.update(bar, on_collision=lambda e: e)
>>> foo
{'a': 1, 'on_collision':  at 0x10b8df598>}

> `updator` being a simple function like this one:
>
> def updator(updated, updator, key) -> Any:
> if key == "related":
> return updated[key].update(updator[key])
>
> if key == "tags":
> return updated[key] + updator[key]
>
> if key in ["a", "b", "c"]: # Those
> return updated[key]
>
> return updator[key]
>
> There's nothing here that couldn't be made today by using a custom
> update function, but leaving the burden of checking for values that are
> in both and actually inserting the new values to Python's language, and
> keeping on our side only the parts that are specific to our use case,
> makes in my opinion the code more readable, with fewer possible bugs and
> possibly better optimization.
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Brice Parent


Le 05/03/2019 à 23:40, Greg Ewing a écrit :

Steven D'Aprano wrote:

The question is, is [recursive merge] behaviour useful enough and

> common enough to be built into dict itself?

I think not. It seems like just one possible way of merging
values out of many. I think it would be better to provide
a merge function or method that lets you specify a function
for merging values.

That's what this conversation led me to. I'm not against the addition 
for the most general usage (and current PEP's describes the behaviour I 
would expect before reading the doc), but for all other more specific 
usages, where we intend any special or not-so-common behaviour, I'd go 
with modifying Dict.update like this:


foo.update(bar, on_collision=updator)  # Although I'm not a fan of the 
keyword I used


`updator` being a simple function like this one:

def updator(updated, updator, key) -> Any:
    if key == "related":
    return updated[key].update(updator[key])

    if key == "tags":
    return updated[key] + updator[key]

    if key in ["a", "b", "c"]:  # Those
    return updated[key]

    return updator[key]

There's nothing here that couldn't be made today by using a custom 
update function, but leaving the burden of checking for values that are 
in both and actually inserting the new values to Python's language, and 
keeping on our side only the parts that are specific to our use case, 
makes in my opinion the code more readable, with fewer possible bugs and 
possibly better optimization.



___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-06 Thread Stefan Behnel
INADA Naoki schrieb am 05.03.19 um 08:03:> On Tue, Mar 5, 2019 at 12:02 AM
Stefan Behnel wrote:
>> INADA Naoki schrieb am 04.03.19 um 11:15:
>>> Why statement is not enough?
>> 
>> I'm not sure I understand why you're asking this, but a statement is 
>> "not enough" because it's a statement and not an expression. It does 
>> not replace the convenience of an expression.
> 
> It seems tautology and say nothing.

That's close to what I thought when I read your question. :)


> What is "convenience of an expression"?

It's the convenience of being able to write an expression that generates
the thing you need, rather than having to split code into statements that
create it step by step before you can use it.

Think of comprehensions versus for-loops. Comprehensions are expressions
that don't add anything to the language that a for-loop cannot achieve.
Still, everyone uses them because they are extremely convenient.


> Is it needed to make Python more readable language?

No, just like comprehensions, it's not "needed". It's just convenient.


> Anyway, If "there is expression" is the main reason for this proposal, 
> symbolic operator is not necessary.

As said, "needed" is not the right word. Being able to use a decorator
closes a gap in the language. Just like list comprehensions fit generator
expressions and vice versa. There is no "need" for being able to write

[x**2 for x in seq]
{x**2 for x in seq}

when you can equally well write

list(x**2 for x in seq)
set(x**2 for x in seq)

But I certainly wouldn't complain about that redundancy in the language.


> `new = d1.updated(d2)` or `new = dict.merge(d1, d2)` are enough. Python 
> preferred name over symbol in general. Symbols are readable and 
> understandable only when it has good math metaphor.
> 
> Sets has symbol operator because it is well known in set in math, not 
> because set is frequently used.
> 
> In case of dict, there is no simple metaphor in math.

So then, if "list+list" and "tuple+tuple" wasn't available through an
operator, would you also reject the idea of adding it, argueing that we
could use this:

L = L1.extended(L2)

I honestly do not see the math relation in concatenation via "+".

But, given that "+" and "|" already have the meaning of "merging two
containers into one" in Python, I think it makes sense to allow that also
for dicts.


> It just cryptic and hard to Google.

I honestly doubt that it's something people would have to search for any
more than they have to search for the list "+" operation. My guess is that
it's pretty much what most people would try first when they have the need
to merge two dicts, and only failing that, they would start a web search.

In comparison, very few users would be able to come up with "{**d1, **d2}"
on their own, or even "d1.updated(d2)".

My point is, given the current language, "dict+dict" is a gap that is worth
closing.

Stefan

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-05 Thread Josh Rosenberg
On Wed, Mar 6, 2019 at 12:08 AM Guido van Rossum  wrote:

> On Tue, Mar 5, 2019 at 3:50 PM Josh Rosenberg <
> shadowranger+pythonid...@gmail.com> wrote:
>
>>
>> On Tue, Mar 5, 2019 at 11:16 PM Steven D'Aprano 
>> wrote:
>>
>>> On Sun, Mar 03, 2019 at 09:28:30PM -0500, James Lu wrote:
>>>
>>> > I propose that the + sign merge two python dictionaries such that if
>>> > there are conflicting keys, a KeyError is thrown.
>>>
>>> This proposal is for a simple, operator-based equivalent to
>>> dict.update() which returns a new dict. dict.update has existed since
>>> Python 1.5 (something like a quarter of a century!) and never grown a
>>> "unique keys" version.
>>>
>>> I don't recall even seeing a request for such a feature. If such a
>>> unique keys version is useful, I don't expect it will be useful often.
>>>
>>
>> I have one argument in favor of such a feature: It preserves
>> concatenation semantics. + means one of two things in all code I've ever
>> seen (Python or otherwise):
>>
>> 1. Numeric addition (including element-wise numeric addition as in
>> Counter and numpy arrays)
>> 2. Concatenation (where the result preserves all elements, in order,
>> including, among other guarantees, that len(seq1) + len(seq2) == len(seq1 +
>> seq2))
>>
>> dict addition that didn't reject non-unique keys wouldn't fit *either*
>> pattern; the main proposal (making it equivalent to left.copy(), followed
>> by .update(right)) would have the left hand side would win on ordering, the
>> right hand side on values, and wouldn't preserve the length invariant of
>> concatenation. At least when repeated keys are rejected, most concatenation
>> invariants are preserved; order is all of the left elements followed by all
>> of the right, and no elements are lost.
>>
>
> I must by now have seen dozens of post complaining about this aspect of
> the proposal. I think this is just making up rules (e.g. "+ never loses
> information") to deal with an aspect of the design where a *choice* must be
> made. This may reflect the Zen of Python's "In the face of ambiguity,
> refuse the temptation to guess." But really, that's a pretty silly rule
> (truly, they aren't all winners). Good interface design constantly makes
> choices in ambiguous situations, because the alternative is constantly
> asking, and that's just annoying.
>
> We have a plethora of examples (in fact, almost all alternatives
> considered) of situations related to dict merging where a choice is made
> between conflicting values for a key, and it's always the value further to
> the right that wins: from d[k] = v (which overrides the value when k is
> already in the dict) to d1.update(d2) (which lets the values in d2 win),
> including the much lauded {**d1, **d2} and even plain {'a': 1, 'a': 2} has
> a well-defined meaning where the latter value wins.
>
> Yeah. And I'm fine with the behavior for update because the name itself is
descriptive; we're spelling out, in English, that we're update-ing the
thing it's called on, so it makes sense to have the thing we're sourcing
for updates take precedence.

Similarly, for dict literals (and by extension, unpacking), it's following
an existing Python convention which doesn't contradict anything else.

Overloading + lacks the clear descriptive aspect of update that describes
the goal of the operation, and contradicts conventions (in Python and
elsewhere) about how + works (addition or concatenation, and a lot of
people don't even like it doing the latter, though I'm not that pedantic).

A couple "rules" from C++ on overloading are "*Whenever the meaning of an
operator is not obviously clear and undisputed, it should not be
overloaded.* *Instead, provide a function with a well-chosen name.*"
and "*Always
stick to the operator’s well-known semantics".* (Source:
https://stackoverflow.com/a/4421708/364696 , though the principle is
restated in many other places). Obviously the C++ community isn't perfect
on this (see iostream and <> operators), but they're otherwise pretty
consistent. + means addition, and in many languages including C++ strings,
concatenation, but I don't know of any languages outside the "esoteric"
category that use it for things that are neither addition nor
concatenation. You've said you don't want the whole plethora of set-like
behaviors on dicts, but dicts are syntactically and semantically much more
like sets than sequences, and if you add + (with semantics differing from
both sets and sequences), the language becomes less consistent.

I'm not against making it easier to merge dictionaries. But people seem to
be arguing that {**d1, **d2} is bad because of magic punctuation that
obscures meaning, when IMO:

 d3 = d1 + d2

is obscuring meaning by adding yet a third rule for what + means,
inconsistent with both existing rules (from both Python and the majority of
languages I've had cause to use). A named method (class or instance) or
top-level function (a la sorted) is more explicit, easier to look up (after
all, the 

  1   2   >