add __contains__ into the "type" object

where we use types? almost: isinstance(obj, T); # issubclass(S, T); Note that TYPE is SET; if we add __contains__ and __le__ into "type", then things become: obj in T; # S <= T; # if only not misleading to a total ordering example: def __getitems__(self, i): if i in Integral: ... elif i in slice: ... # Save "(,)". Really, I prefer to type "lambda:;" than "()". # I fail to modify the "type" object, since it is a C-object.

On Wed, Mar 01, 2017 at 07:02:23AM +0800, 语言破碎处 wrote:
What does that mean? I don't understand.
But obj is **not** in T, since T is a type, not a container. "is-a" tests are not the same as "in" tests. They are completely unrelated comparisons. http://www.w3resource.com/java-tutorial/inheritance-composition-relationship... The Wikipedia page on is-a is terribly complicated, but folks may get something from it: https://en.wikipedia.org/wiki/Is-a -- Steve

2017-02-28 15:12 GMT-08:00 Steven D'Aprano <steve@pearwood.info>:
But in type theory, types are sets in some sense. For example, the bool type is the set {True, False}, and the int type is the infinite set {..., -1, 0, 1, ...}. Similarly, typing.py has a Union type: Union[A, B] is the union of the types A and B. Subclasses are subsets of their parent classes, because their set of possible values is a subset of the possible values of their parent class. The OP seems to be proposing that we reflect this identity between types and sets in Python by spelling "isinstance(obj, T)" as "obj in T" and "issubclass(S, T)" as "S <= T". This proposal has some solid theory behind it and I don't think it would be hard to implement, but it doesn't seem like a particularly useful change to me. It wouldn't really enable anything we can't do now, and it may be confusing to people reading code that "obj in list" does something completely different from "obj in list()".

On Tue, Feb 28, 2017 at 03:35:31PM -0800, Jelle Zijlstra wrote:
So? Compare to "fn" vs "fn()" now. Yes, some people are confused. So what. You *do* have to learn things. And "enable anything we can't do now". That argument was used any number of times on this list, and even before this very list even existed. Still, we got decorators (they don't enable anything we couldn't do without them, and we actually can still do what they do without using them). "isinstane" and "issubclass" are explicit! Yay!... and decorators are "implicit", and wouldn't you know it, they *do* confuse people. I'm +.05 (and no, that's not because I finally see an idea of <sorry can't type that name> that I actually think has some merit). Maybe even +1, given that isinstance(obj, class) is rather bulky. Okay, make that a +1. Bye, J

On Thu, Mar 02, 2017 at 04:23:08AM +0100, Jürgen A. Erhard wrote:
I don't understand what this comparison is supposed to show. `fn` is a name. `fn()` does a function call on whatever object is bound to `fn`. How is that relevant to the question of adding a completely separate set-like interface to isinstance and issubclass?
It has been used many times. That is because it is a GOOD argument. We don't just add every single random feature that people can think of. ("Hey, wouldn't it be AWESOME if Class*str returned a list of class methods that contained the string in their name???") The new functionality, spelling or syntax has to add some benefit to make up for the extra cost: - the cost to develop this new feature or syntax; - the cost to write new tests for this feature; - the cost to document it; - the cost to documentation in books and the web that are now obsolete or incorrect; - the cost for people to learn this feature; - the cost for people to decide whether to use the old or the new spelling; and so forth.
Indeed, but you are missing that decorator syntax brings some VERY important benefits that are a clear win over the old way: @decorate def spam(): ... versus def spam(): ... spam = decorate(spam) The decorator syntax avoids writing the function name three times, but more importantly, it puts the decoration right at the start of the function, next to the signature, where it is more obvious and easier to see, instead of way down the end, which might be many lines or even pages away. That's a very big win that makes decorator syntax the One Obvious Way to decorate functions and classes. Compare to the OP's suggestion: 23 in int This doesn't even make sense unless you have been exposed to a very small subset of theoretical computer science which treats classes as sets and instances as elements of those sets. To everyone else, especially those with a background in "ordinary" OOP, it looks like nonsense. (Personally, I'm a bit dubious about conflating is-a and element-of operations in this way, it feels like a category mistake to me, but for the sake of the argument I'll accept it.) So the benefit applies only to a tiny subset of users, but the cost is carried by everyone. -- Steve

On Fri, Mar 3, 2017 at 12:44 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I've seen languages in which types can be the RHO of 'is', so this would look like: 23 is int Obviously that depends on types not themselves being first-class objects, but it makes a lot more sense than a containment check. But I'm trying to think how frequently I do *any* type checking in production code. It's not often. It doesn't need syntax. isinstance(23, int) works fine. ChrisA

By itself, I don't see using the ``in`` syntax to check for ``instanceof`` as a big benefit, given the overhead of learning that new concept. However, given in the light of a bigger concept, I think it may make more sense. If we accept that it may be desirable to work with types as set-like objects, apart from (in most cases) iteration, then some other shorthands become reasonable too. Other set operators, such as:: list <= object # issubclass(list, object) Plus the other obvious comparisons. Other set operators can be used for typing:: list | set # same or similar to typing.Union[list, set] mixin1 & mixin2 # Represents classes that inherit from mixin1 and mixin2 When we bring typing into it, it would be cool if those resultant values also were able to do instance and subclass checks. They currently raise an error, but I think it would be possible to do if this were all built into ``type``. And, of course, if we're bringing typing to ``type``, we can replace things like ``typing.List[int]`` with ``list[int]``, and putting those directly into signatures. I think it would be somewhat odd to bring in *some* of the set operators to types, but leave off ``__contains__`` and inequality comparisons. This is not a proposal of all of this, just pointing out that there are further applications to this concept. At least in the case of the typing examples, I think that there are some simplifications to be had by thinking this way. Reasons against also exist, of course, but like everything it's a trade-off to consider. I have a repo that starts some of this, though it's currently broken due to lack of love in the middle of a refactor. I haven't tried to add any typing stuff, but that seems like an obvious extension. I wouldn't expect type checkers to work with a 3rd party module like this, but it could help demonstrate the ideas. https://github.com/ryanhiebert/typeset If anyone is interested enough to help flesh out this proof of concept, I'd be grateful for some collaboration, or being let know of other work like it.

On 3/1/17, Steven D'Aprano <steve@pearwood.info> wrote:
Maybe she/he wants to say that it is natural to see class as a collection (at least in set theory https://en.wikipedia.org/wiki/Class_(set_theory) )

A crucial difference between a set and a type is that you cannot explicitly iterate over the elements of a type, so while we could implement x in int to do something useful, we cannot make for x in int: print(x) Because if we could, we could implement Russell's paradox in Python: R = set(x for x in object if x not in x) print(R in R) Bottom line: a set is not a type, even in mathematics. Stephan 2017-03-02 5:38 GMT+01:00 Pavol Lisy <pavol.lisy@gmail.com>:

This suggestion is really problematic IMHO. "isinstance" is a nominal check. I can't ask "isinstance(x, Callable[int, int])" because that would imply solving the halting problem. so "isinstance(x, Y)" does not mean "is it true that x is an element of the type Y" but rather "is it true that x was created by a constructor of some superclass of Y". It is not a type-theoretic question but a question of origin and intent. With regard to readability, this will be completely confusing for me. "in" is a question about inclusion in a collection, not some set-theoretic inclusion. Otherwise we should also as "x in f" as an equivalent to "not not f(x)", as is in set theory. Elazar

__contains__ was introduced to provide a more efficient test than to simply iterate over the elements one by one. I don’t see why something has to be iterable in order to implement __contains__, though. class PositiveInts(int): def __contains__(self, x): return x > 0 N = PostiveInts()
object is not the equivalent of the paradoxical set of all sets. It’s closer to the set of all valid Python values. That includes all valid Python set values, but a Python set is not mathematical set; it’s a *finite* collection of *hashable* values.

On 3/2/17, Stephan Houben <stephanh42@gmail.com> wrote:
:) Problem of Russel paradox was that set was defined intuitively in that time. And it is why **class**, was introduced in set theory then! :) In set theory you could ask if x member of set or x is member of class and difference between set and class is just that set is not same as class. (class is some intuitively defined concept just to avoid paradoxes like Russel's) And python does not implement platonism (https://en.wikipedia.org/wiki/Philosophy_of_mathematics#Platonism) - object doesn't exists until they are created. class int is not infinite in its actuality. (Does not occupy infinite memory) So I think that print(R in R) would print True. Because in the time set is in creation process this object (set) is not member of that set so it would be added to that set. Or maybe it will return False if this incomplete set is not evaluated in process of its creation. It is matter of implementation, but it could be perfectly deterministic. So maybe Russel had to "implement" GIL in mathematics ;) In current python you could ask about "membership" (operator in) where object is not set: if 3 in itertools.count(): # this is ok type(itertools.count()) # this is ok else: set(itertools.count()) # I don't approve this :P python set is not mathematics set too: a = set() a.add(a) # TypeError: unhashable type: 'set' I am -1 about proposal in this moment. I probably understand motivation but I don't see yet that this change could bring enough goodness.

-1. It is already possible to specify what inst in cls means by using a metaclass. For example: class Color(enum.Enum): RED = 1 GREEN = 2 BLUE = 3 some_var = Color.GREEN some_var in Color # True some_var in enum.Enum # False Containment != isinstance() -- ~Ethan~

On Wed, Mar 01, 2017 at 07:02:23AM +0800, 语言破碎处 wrote:
What does that mean? I don't understand.
But obj is **not** in T, since T is a type, not a container. "is-a" tests are not the same as "in" tests. They are completely unrelated comparisons. http://www.w3resource.com/java-tutorial/inheritance-composition-relationship... The Wikipedia page on is-a is terribly complicated, but folks may get something from it: https://en.wikipedia.org/wiki/Is-a -- Steve

2017-02-28 15:12 GMT-08:00 Steven D'Aprano <steve@pearwood.info>:
But in type theory, types are sets in some sense. For example, the bool type is the set {True, False}, and the int type is the infinite set {..., -1, 0, 1, ...}. Similarly, typing.py has a Union type: Union[A, B] is the union of the types A and B. Subclasses are subsets of their parent classes, because their set of possible values is a subset of the possible values of their parent class. The OP seems to be proposing that we reflect this identity between types and sets in Python by spelling "isinstance(obj, T)" as "obj in T" and "issubclass(S, T)" as "S <= T". This proposal has some solid theory behind it and I don't think it would be hard to implement, but it doesn't seem like a particularly useful change to me. It wouldn't really enable anything we can't do now, and it may be confusing to people reading code that "obj in list" does something completely different from "obj in list()".

On Tue, Feb 28, 2017 at 03:35:31PM -0800, Jelle Zijlstra wrote:
So? Compare to "fn" vs "fn()" now. Yes, some people are confused. So what. You *do* have to learn things. And "enable anything we can't do now". That argument was used any number of times on this list, and even before this very list even existed. Still, we got decorators (they don't enable anything we couldn't do without them, and we actually can still do what they do without using them). "isinstane" and "issubclass" are explicit! Yay!... and decorators are "implicit", and wouldn't you know it, they *do* confuse people. I'm +.05 (and no, that's not because I finally see an idea of <sorry can't type that name> that I actually think has some merit). Maybe even +1, given that isinstance(obj, class) is rather bulky. Okay, make that a +1. Bye, J

On Thu, Mar 02, 2017 at 04:23:08AM +0100, Jürgen A. Erhard wrote:
I don't understand what this comparison is supposed to show. `fn` is a name. `fn()` does a function call on whatever object is bound to `fn`. How is that relevant to the question of adding a completely separate set-like interface to isinstance and issubclass?
It has been used many times. That is because it is a GOOD argument. We don't just add every single random feature that people can think of. ("Hey, wouldn't it be AWESOME if Class*str returned a list of class methods that contained the string in their name???") The new functionality, spelling or syntax has to add some benefit to make up for the extra cost: - the cost to develop this new feature or syntax; - the cost to write new tests for this feature; - the cost to document it; - the cost to documentation in books and the web that are now obsolete or incorrect; - the cost for people to learn this feature; - the cost for people to decide whether to use the old or the new spelling; and so forth.
Indeed, but you are missing that decorator syntax brings some VERY important benefits that are a clear win over the old way: @decorate def spam(): ... versus def spam(): ... spam = decorate(spam) The decorator syntax avoids writing the function name three times, but more importantly, it puts the decoration right at the start of the function, next to the signature, where it is more obvious and easier to see, instead of way down the end, which might be many lines or even pages away. That's a very big win that makes decorator syntax the One Obvious Way to decorate functions and classes. Compare to the OP's suggestion: 23 in int This doesn't even make sense unless you have been exposed to a very small subset of theoretical computer science which treats classes as sets and instances as elements of those sets. To everyone else, especially those with a background in "ordinary" OOP, it looks like nonsense. (Personally, I'm a bit dubious about conflating is-a and element-of operations in this way, it feels like a category mistake to me, but for the sake of the argument I'll accept it.) So the benefit applies only to a tiny subset of users, but the cost is carried by everyone. -- Steve

On Fri, Mar 3, 2017 at 12:44 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I've seen languages in which types can be the RHO of 'is', so this would look like: 23 is int Obviously that depends on types not themselves being first-class objects, but it makes a lot more sense than a containment check. But I'm trying to think how frequently I do *any* type checking in production code. It's not often. It doesn't need syntax. isinstance(23, int) works fine. ChrisA

By itself, I don't see using the ``in`` syntax to check for ``instanceof`` as a big benefit, given the overhead of learning that new concept. However, given in the light of a bigger concept, I think it may make more sense. If we accept that it may be desirable to work with types as set-like objects, apart from (in most cases) iteration, then some other shorthands become reasonable too. Other set operators, such as:: list <= object # issubclass(list, object) Plus the other obvious comparisons. Other set operators can be used for typing:: list | set # same or similar to typing.Union[list, set] mixin1 & mixin2 # Represents classes that inherit from mixin1 and mixin2 When we bring typing into it, it would be cool if those resultant values also were able to do instance and subclass checks. They currently raise an error, but I think it would be possible to do if this were all built into ``type``. And, of course, if we're bringing typing to ``type``, we can replace things like ``typing.List[int]`` with ``list[int]``, and putting those directly into signatures. I think it would be somewhat odd to bring in *some* of the set operators to types, but leave off ``__contains__`` and inequality comparisons. This is not a proposal of all of this, just pointing out that there are further applications to this concept. At least in the case of the typing examples, I think that there are some simplifications to be had by thinking this way. Reasons against also exist, of course, but like everything it's a trade-off to consider. I have a repo that starts some of this, though it's currently broken due to lack of love in the middle of a refactor. I haven't tried to add any typing stuff, but that seems like an obvious extension. I wouldn't expect type checkers to work with a 3rd party module like this, but it could help demonstrate the ideas. https://github.com/ryanhiebert/typeset If anyone is interested enough to help flesh out this proof of concept, I'd be grateful for some collaboration, or being let know of other work like it.

On 3/1/17, Steven D'Aprano <steve@pearwood.info> wrote:
Maybe she/he wants to say that it is natural to see class as a collection (at least in set theory https://en.wikipedia.org/wiki/Class_(set_theory) )

A crucial difference between a set and a type is that you cannot explicitly iterate over the elements of a type, so while we could implement x in int to do something useful, we cannot make for x in int: print(x) Because if we could, we could implement Russell's paradox in Python: R = set(x for x in object if x not in x) print(R in R) Bottom line: a set is not a type, even in mathematics. Stephan 2017-03-02 5:38 GMT+01:00 Pavol Lisy <pavol.lisy@gmail.com>:

This suggestion is really problematic IMHO. "isinstance" is a nominal check. I can't ask "isinstance(x, Callable[int, int])" because that would imply solving the halting problem. so "isinstance(x, Y)" does not mean "is it true that x is an element of the type Y" but rather "is it true that x was created by a constructor of some superclass of Y". It is not a type-theoretic question but a question of origin and intent. With regard to readability, this will be completely confusing for me. "in" is a question about inclusion in a collection, not some set-theoretic inclusion. Otherwise we should also as "x in f" as an equivalent to "not not f(x)", as is in set theory. Elazar

__contains__ was introduced to provide a more efficient test than to simply iterate over the elements one by one. I don’t see why something has to be iterable in order to implement __contains__, though. class PositiveInts(int): def __contains__(self, x): return x > 0 N = PostiveInts()
object is not the equivalent of the paradoxical set of all sets. It’s closer to the set of all valid Python values. That includes all valid Python set values, but a Python set is not mathematical set; it’s a *finite* collection of *hashable* values.

On 3/2/17, Stephan Houben <stephanh42@gmail.com> wrote:
:) Problem of Russel paradox was that set was defined intuitively in that time. And it is why **class**, was introduced in set theory then! :) In set theory you could ask if x member of set or x is member of class and difference between set and class is just that set is not same as class. (class is some intuitively defined concept just to avoid paradoxes like Russel's) And python does not implement platonism (https://en.wikipedia.org/wiki/Philosophy_of_mathematics#Platonism) - object doesn't exists until they are created. class int is not infinite in its actuality. (Does not occupy infinite memory) So I think that print(R in R) would print True. Because in the time set is in creation process this object (set) is not member of that set so it would be added to that set. Or maybe it will return False if this incomplete set is not evaluated in process of its creation. It is matter of implementation, but it could be perfectly deterministic. So maybe Russel had to "implement" GIL in mathematics ;) In current python you could ask about "membership" (operator in) where object is not set: if 3 in itertools.count(): # this is ok type(itertools.count()) # this is ok else: set(itertools.count()) # I don't approve this :P python set is not mathematics set too: a = set() a.add(a) # TypeError: unhashable type: 'set' I am -1 about proposal in this moment. I probably understand motivation but I don't see yet that this change could bring enough goodness.

-1. It is already possible to specify what inst in cls means by using a metaclass. For example: class Color(enum.Enum): RED = 1 GREEN = 2 BLUE = 3 some_var = Color.GREEN some_var in Color # True some_var in enum.Enum # False Containment != isinstance() -- ~Ethan~
participants (12)
-
Chris Angelico
-
Clint Hepner
-
Eric V. Smith
-
Ethan Furman
-
Jelle Zijlstra
-
Jürgen A. Erhard
-
Pavol Lisy
-
Ryan Hiebert
-
Stephan Houben
-
Steven D'Aprano
-
אלעזר
-
语言破碎处