evhub / coconut

Simple, elegant, Pythonic functional programming.
http://coconut-lang.org
Apache License 2.0
4.05k stars 120 forks source link

`multiset` methods inherited from `Counter` should always return a `multiset` when used with `multiset`s #759

Closed Starwort closed 1 year ago

Starwort commented 1 year ago

When OR-ing a multiset together, I'd expect that the counts of the items in each multiset would be added together (I.E. m{1, 1, 2, 3} | m{1, 2, 3, 3} == m{1, 1, 1, 2, 2, 3, 3, 3}) but this just delegates to the default Counter behaviour (which takes the highest number from each set) - which IMO is unintuitive for an object representing a multiset

Counter has a method 'update', which could be used over the items of the other side to implement the more intuitive behaviour

evhub commented 1 year ago

The | operator is meant to represent the union, which for multisets in mathematics is defined as the max of the counts in the multisets being unioned, which means the default behavior there is correct. What you're thinking of is the multiset sum, which, as the name suggests, can be achieved just by adding two multisets together rather than unioning them:

$ coconut
Coconut Interpreter v3.0.1-post_dev15:
(enter 'exit()' or press Ctrl-D to end)
>>> m{1, 1} + m{1, 2}
Counter({1: 3, 2: 1})

Though, looking at the output there, it looks like it gives back a vanilla Counter, which does look like a bug to me—that should be a multiset, so I'll leave this issue open to fix that.