On Mon, Aug 10, 2020 at 2:20 PM Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
haael writes:

> Could we add the idea of "negative" sets to Python?  That means
> sets that contain EVERYTHING EXCEPT certain elements.

This is usually called the "complement" of a set.  Since (in set
theory) there is no set of all sets, "absolute" complement is an
unfounded concept.  The idea of having a universe and defining
"absolute complement" as complement relative to the universe is often
adopted, but it has set-theoretic problems (the universe doesn't have
a powerset, for one thing), and frequently you end up with a hierarchy
of universes (categorists who try build category theory on set theory
run into that a lot).

Yes, we can implement things in Python that aren't allowed in formal mathematics and some fun questions arise. What should `set.UNIVERSAL in set.UNIVERSAL` return? Bertrand Russell thinks it's False.

Considering those points, this proposal seems very abstract.  I think
it's fun to think about, and maybe it has practical applications in
constructing other sets.  But a "set" that isn't iterable, and whose
"in" is logically equivalent to "not in" its complement (which is a
Python set!), doesn't seem directly useful in itself.

I think it'd be best if such a class was not a subclass of the Set ABC, since it's not iterable. You can use it like a set in certain situations where you know what you're doing, but avoid passing it to generic code that expects a real set.

I think this is one where you need to present both use cases and an
implementation.  Speaking of implementations and fun:

> First, let's have a universal set that contains everything.
>
>      assert element in set.UNIVERSAL

For what values of "everything"?  Python sets cannot contain all the
objects of Python.  Specifically, an element of a set must be
hashable.  Will that be true for your universal set?

The builtin set requires hashability, but you could certainly implement a subclass of the Set ABC that satisfies all contracts and accepts non-hashable elements. It would just be much less performant.

> However REMOVING an element from the set puts it on "negative list".
>
>      myset = set.UNIVERSAL

Shouldn't this be "myset = copy(set.UNIVERSAL)"?

You'd like it to be "myset = set(set.UNIVERSAL)", I guess, and that
indeed would require adding set.UNIVERSAL to Python.

I think the better API would be `myset = UniversalSet()`.

Anyway, in the end, I think we all agree that this is fun to think about but too obscure for the Python language itself. Maybe you could put it on PyPI.