On Fri, 13 May 2016 03:07 pm, Ben Finney wrote: > Howdy all, > > Ever since Python's much-celebrated Grand Unification of classes and > types, I have used those terms interchangeably: every class is a type, > and every type is a class. > > That may be an unwise conflation. With the recent rise of optional type > annotation in Python 3, more people are speaking about the important > distinction between a class and a type. [...] > As a Bear of Little Brain, this leaves me clueless. What is the > distinction Guido alludes to, and how are Python classes not also types? > > And why is this distinction important, and who moved my cheesecake?
You're not alone. Unfortunately, this confusion is endemic in IT and on the internet. People use types all the time, but without understanding that there are (at least) two related but distinct meanings for the word. Even though it isn't specifically about this distinction, you should start by reading this essay about the distinction between static and dynamic typing here: https://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/ Then you should read Guido's PEP 483 on "gradual typing": https://www.python.org/dev/peps/pep-0483/ And this answer on Stackoverflow: http://stackoverflow.com/a/25114770 (Note that despite the question specifying language agnostic answers, the second most highly-rated answer is language specific.) The Wikipedia article is heavy going, but worth reading: https://en.wikipedia.org/wiki/Type_theory As Python programmers, the simplest way to look at this question is: (1) Class (also known as a "type", although for the avoidance of confusion I shall avoid that terminology here) in the Python sense is an entity which tells the interpreter what methods and attributes a value has. In other words, classes define behaviour. In Python classes are "first-class values" and can be created on the fly, bound to names, put inside lists, etc. This is not essential to the concept though, many languages, such as Java, do not treat classes as first-class. Unfortunately, for historical reasons, the function[1] which returns the class of a value is called "type()". And the class of all classes (the metaclass) is also called "type". Which made type and class synonyms from Python 2.2 onwards. (2) Type, in the PEP 483/484 sense, is a label which tells the static type-checker what kind of values are acceptable in a particular place. This is the "type theory" sense as in the Wikipedia article. In principle these PEP 484 types could be completely abstract, but Python's typing module will generally use classes (sense 1 above) to implement these label. (3) In Python especially, the differences between (1) and (2) are more theoretical than practical, but there are a couple of obvious exceptions: - Union types should be considered a purely abstract label. (In practice, they'll actually be implemented as a class, but that's just an implementation detail.) Unions cannot be instantiated, nor subclassed. For example, take this example: py> import typing py> Foo = typing.Union[str, int] Foo is now a label to tell the type-checker you will accept "a str, or an int, but nothing else". It is *not* a subclass of str and int. There is no such thing as an instance of Foo, nor can you subclass it. If you try, you get a TypeError: py> Foo() [...] TypeError: Cannot instantiate <class 'typing.UnionMeta'> class Bar(Foo): pass [...] TypeError: Cannot subclass typing.Union[str, int] This is from Python 3.6 pre-alpha. The messages may change in the future. Foo is only used as a purely abstract label to tell the type-checker to accept either a str, or an int. So in that sense, although the Python implementation of Foo is a class object, that's just a detail of the implementation. - The other obvious example is Any. Like Unions, Any cannot be instantiated or subclassed and is intended as a purely abstract label for "anything at all". One can consider Any to be the equivalent of a Union of "all possible types", and it basically exists for the type-checker to record a state of maximum ignorance. ("I don't know what this will be, it could be anything.") So types and classes essentially have different purposes, even though they overlap. Types (in this "type theory", PEP 484 sense) are for proving compile-time facts about code. Classes (in Python) are for specifying the behaviour and implementation of objects. [1] Actually, the function "type()" and the class "type" are implemented as the same object, which does two different things depending on how many arguments it gets. With one argument, type(x) returns the class of x. With three arguments, type(name, bases, namespace) creates and returns a new class. -- Steven -- https://mail.python.org/mailman/listinfo/python-list