X Tutup

[Python-ideas] Counter comparison

Raymond Hettinger raymond.hettinger at gmail.com
Sun Nov 23 03:51:30 CET 2014


> On Nov 22, 2014, at 8:06 AM, Antoine Pitrou <solipsis at pitrou.net> wrote:
> 
> Your insistance on defending irrational API decisions is staggering.

Gee, that's a little harsh.

I'm trying to exercise good judgment over API design decisions.  You may not agree, but I should at least share my thought process:

* Even for regular sets, overriding the comparison operators was a bit dodgy leading to some oddities -- one because it is partial ordering that confuses sort() and another because of people's propensity to write "set_a < set_b" when they really meant "set_a <= set_b".

* Also, I have reservations about having added any multi-set operations to counters in the first place.  That seems to be the only the part of counter API that has agitated or confused anyone.  The problems arise the counter is an extension of the dict API rather than being a fully encapsulated bag or multiset that can prevent counts from being zero, negative, or non-integral.  In other words, the multi-set operations may have added some value but they weren't a perfect fit.  

* With those two thoughts in mind, I had some reluctance to add anything "doubly dodgy" by adding multi-set comparisons.

* Next, there is some question of what the comparison operations should do in the presence of zeros or negative counts.  Inspired by the design principles in the decimal module (all numbers are exact and rounding is only applied after operations rather than before), the current multi-set operations eliminate non-negative results after the operation rather than before.   That said, I don't know whether it makes sense multi-set comparison to follow that model (for consistency) or to clean-up the inputs prior to the operation.  For example, should Counter(a=-1, b=0, c=1) be considered a proper subset of Counter(c=2, d=3, e=0, f=-1)?    There are reasons to say yes and reasons you could say no.  To inform the best possible decision, it would be great to have real use cases to guide the design process.

* Which gets us to use cases.  When Ram suggested multiset operations in a feature request, all he said was "I suggest implementing `Counter.__lt__` which will be a partial order, similarly to `set.__lt__`.".  There was no mention of use case until later where all he said was "I needed it for an internal calculation in a combinatorics package I'm writing.
" and he did not elaborate further.  As the discussion evolved, no further use case detail emerged.  However, later in the discussion it because clear that several of the posters either thought the idea didn't make sense or were confused about what the it should do.   Near the end of the discussion, the OP said he had given up on the idea because of the issues regarding the "hybrid mapping/multiset" design.  After the -1s, examples of people being confused, and the OP's withdrawal, I stepped in and closed the feature request.

* This current thread did not begin with a use case either.  It was more along the lines of "in for a penny, in for a pound".  Since some multiset operations were implemented, maybe you should do them all.

For the reasons listed above, I prefer to be conservative and not expand the API further.  For the most part, people seem to use counters for counting.  They are good at that task and popular.  I don't feel a strong need to expand the API into dodgy territory unless really good use cases arise to guide the design and make it feel like the added benefits were worth moving further on to shaky ground.

Also, I've taken some comfort in knowing that since a counter is a dictionary subclass, it is trivially easy to extend for users.  If the user can already meet any perceived need by writing "all(c[k] < d[k] for k in c)", then I'm not sure we can make much of a value add.

You may not agree with the outcome of my thought process, but it is unfair to call it irrational.

not-everything-that-can-be-done-should-be-done-ly yours,


Raymond



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20141122/b52be67a/attachment-0001.html>


More information about the Python-ideas mailing list
X Tutup