Christopher Barker writes:

 > But to a couple points:
 > 
 > > Why do you want to add them?  The point of an ABC is that it is
 > > Abstract.  This doesn't just mean "can't instantiate", it also means
 > > "only the defining features."
 > 
 > Well, Python's history makes all this a bit backward -- most (all?) of the
 > ABCs existed in concrete form before there wre abstract versions.

"History" -- that aspect of human recollection that makes everything a
bit backward. ;-)

 > But anyway, as I understand it, "abstract" means "not implemented",
 > which is completely separate from "only the defining features" --
 > ABCs define the API, not the feature set.

This is also historical, as you point out:

 > And the fact is that Python has a somewhat arbitrary mix of operators
 > implemented by dunders, protocols implemented by dunders (like the len()
 > function) and regular old methods -- all of these are in the ABCs.
 > 
 > So I don't think there's any clear principle here -- do we want
 > .union() and friends to be part of the standard set API or not? 
 > It's simply a choice.

But it's not that simple, as you have made plain with your references
to history.  Such a choice creates a precedent aka principle.

 > Judging from some of the arguments in other threads, I suspect some
 > people think that ALL the regular methods are only there for legacy
 > reasons,

I tend to agree that they're legacy, but I think it's irrelevant to
the discussion.  You are correct to focus on whether adding them is
likely to cause backward compatibility issues, but I don't think an
acceptable degree of backward compatibility is a positive reason to
implement something.

BTW, thank you for clarifying that you aren't (in these posts)
advocating this change.  I shouldn't assume that lack of a disclaimer
means you're advocating rather than arguing a specific point.

 >  > BUT: This *may* be a different case -- the Set ABC (and set
 > >  > duck-typing) is probably far less used than for Sequences.
 > >
 > > I don't know about the Set ABC, but duck-typing is presumably quite
 > > common.  {1}.union([2]) uses set duck-typing.
 > 
 > no it doesn't -- the set.union method takes any iterable -- that's
 > documented:

[list of documentation references omitted]

 > no duck-typing here.

What do you think the type "iterable" is?  It's not a concrete type.
The Iterable ABC is defined to include all classes that provide an
__iter__ method (see Lib/_collections_abc.py).

In other words, "iterable" is a named duck type.  It is defined by
"you can use it as X in 'for y in X'" (or equivalently, applying the
builtin iter to it returns an iterator).  For the purposes of set's
named methods, an "iterable" is "sufficiently set-like" to use set
operations on it.  That's duck typing.

 > > all you need mathematically is the ability to iterate the
 > > argument,
 >
 > which is why it works with any iterable.

That's imprecise.  That's why it's *possible* to make it work with any
iterable.  But Python doesn't always implement things that are
possible, and sometimes it implements possible things that turn out to
be bad ideas, causing great pain in both the use and the fix (eg,
Python 2's union of bytes and str).

 > > The other thing you need mathematically to have a set is the 'in'
 > > operation.  If mutable, you need an idempotent .add, and .remove.
 > 
 > no one is arguing that the ABC doesn't provide the minimum API for a
 > mathematical set here.

Nor do I claim they did.  My point is that the mathematical minimum is
far less than what Python provides, and the "practicality" koan
applies, so we provided a lot more than the minimum.  Do we need to
provide near duplicate methods that coerce iterables to set?  I don't
know, somebody needs to argue the practicalities.

 > > Of course convenience counts.  It's not obvious to me whether the
 > > convenience of having those methods outweighs the parsimony of only
 > > implementing the dunders.
 > 
 > I had to go look up "parsimony" to make sure -- and I still don't
 > know what you're point is. Maybe that's not the word you meant?

"Parsimony" here is just a formal term for "YAGNI, so don't waste time
typing it".

 > > In fact, it's not obvious to me whether there's *any* convenience
 > > to having those methods.  Shouldn't we want to encourage the use
 > > of the more concise and less cluttered operators, which also have
 > > the advantage that either operand can provide the implementation?
 > 
 > Well: two points:
 > 
 > 1) why does the built in set object have them? Maybe it shouldn't, but it
 > does, so there is something to be said fro making other "Sets" in the
 > standard library the same.

There may be something to say *for* doing it, but "we did it over
there" is more of a "it's possible" than a reason for.

 > 2) the advantage, maybe small, and made by the OP, is that the
 >    methods work on any iterable, rather than only on sets. Is that
 >    a big deal? not huge, but it is nice sometimes.

I would tend to go with "Explicit is better than implicit" unless the
coercion of iterable to set is frequently useful.  Treating the
results as abstract collections, where l = [1, 2, 1] and s = {1},
l.extend(s) and s.union(l) are quite different things.  The point is
not that I think the use of set.union on arbitrary iterables *is*
frequently buggy; it's that without frequent use, there's little
experience on which to base a judgment.  (I'm not making a claim about
frequency.  I personally have never used those methods on non-sets,
YMMV.)

 > The OP didn't want to make their own, they wanted built in set like
 > objects to behave more like sets (dict views, in particular).

I'm not criticizing the OP.  I'm pushing back on the idea, on the
usual grounds of "why should all users of Python bear the burden of a
slightly larger standard programming environment, and the maintainers
the burden of providing and maintaining it?"  The status quo wins
ties.

 > But anyway, if we're going to say "derive from it, or construct one." then
 > why have ABCs at all ?!?

Nobody is arguing that "derive from it, or construct the duck type" is
*always* the answer.

The reason for having ABCs is that names are powerful.  You can
describe a duck type as "all objects that have __iter__ and __next__",
but it's also useful to have the name "Iterator" for the collection of
all such objects.

Also, many ABCs provide useful generic implementations.

 > > What's the point?  You want to add "There should be two-- and
 > > preferably exactly two --obvious ways to do it" to the Zen?

 > tell that to the author of the built in set object -- that decision was
 > made long ago.

Which means that backward compatibility with existing code is
important, and therefore those methods weren't removed in Python 3.0,
and probably won't be removed.  "Although practicality beats purity"
overrides any of the other koans in the right situations, and backward
compatibility is one of the most important factors.  "Practicality"
also is the exception that justifies adding new ways to do old
behaviors.

 > Anyway, this is not a big deal to not add -- but it's not a big deal to
 > add, either.

An excellent summary of your position, which I now understand. ;-)
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/Z5EI2DCU2UFTVQLTSQEPPY3TSQOIQVFM/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to