Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #108578 > unrolled thread

Distinction between “class” and “type”

Started byBen Finney <ben+python@benfinney.id.au>
First post2016-05-13 15:07 +1000
Last post2016-05-14 15:05 +1000
Articles 5 — 5 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Distinction between “class” and “type” Ben Finney <ben+python@benfinney.id.au> - 2016-05-13 15:07 +1000
    Re: Distinction between “class” and “type” Rustom Mody <rustompmody@gmail.com> - 2016-05-12 22:21 -0700
    Re: Distinction between “class” and “type” Paul Rubin <no.email@nospam.invalid> - 2016-05-12 23:42 -0700
      Re: Distinction between “class” and   “type” Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-05-13 20:24 +1200
    Re: Distinction between “class” and “type” Steven D'Aprano <steve@pearwood.info> - 2016-05-14 15:05 +1000

#108578 — Distinction between “class” and “type”

FromBen Finney <ben+python@benfinney.id.au>
Date2016-05-13 15:07 +1000
SubjectDistinction between “class” and “type”
Message-ID<mailman.623.1463116040.32212.python-list@python.org>
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.

This recent message from GvR, discussing a relevant PEP, advocates
keeping them separate:

    PEP 484 […] tries to make a clear terminological between classes
    (the things you have at runtime) and types (the things that type
    checkers care about).

    There's a big overlap because most classes are also types -- but not
    the other way around! E.g. Any is a type but not a class (you can
    neither inherit from Any nor instantiate it), and the same is true
    for unions and type variables. […]

    <URL:https://mail.python.org/pipermail/python-ideas/2016-May/040237.html>

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?

-- 
 \        “It is the responsibility of intellectuals to tell the truth |
  `\                    and to expose lies.” —Noam Chomsky, 1967-02-23 |
_o__)                                                                  |
Ben Finney

[toc] | [next] | [standalone]


#108580

FromRustom Mody <rustompmody@gmail.com>
Date2016-05-12 22:21 -0700
Message-ID<96254278-f3b9-4e12-a5b6-dbf29e20d386@googlegroups.com>
In reply to#108578
On Friday, May 13, 2016 at 10:37:34 AM UTC+5:30, 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.
> 
> This recent message from GvR, discussing a relevant PEP, advocates
> keeping them separate:
> 
>     PEP 484 […] tries to make a clear terminological between classes
>     (the things you have at runtime) and types (the things that type
>     checkers care about).
> 
>     There's a big overlap because most classes are also types -- but not
>     the other way around! E.g. Any is a type but not a class (you can
>     neither inherit from Any nor instantiate it), and the same is true
>     for unions and type variables. […]
> 
>     <URL:https://mail.python.org/pipermail/python-ideas/2016-May/040237.html>
> 
> 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?

I cannot speak for Guido.
However there is a well-known confusion here, most recently spelt out in
Bob Harper's epochal book:
http://www.cs.cmu.edu/~rwh/pfpl.html

If types are compile time things then they are part of the *syntax* of the language
If types are runtime things they are some kind of tags attached to objects *at runtime*

When a language like python with a clear historical orientation towards the second
starts embracing the first, it is natural that people start getting confused --
which I suspect includes Guido.

[toc] | [prev] | [next] | [standalone]


#108586

FromPaul Rubin <no.email@nospam.invalid>
Date2016-05-12 23:42 -0700
Message-ID<87shxm4fxh.fsf@jester.gateway.pace.com>
In reply to#108578
Ben Finney <ben+python@benfinney.id.au> writes:
>     There's a big overlap because most classes are also types -- but not
>     the other way around! E.g. Any is a type but not a class (you can
>     neither inherit from Any nor instantiate it), and the same is true
>     for unions and type variables. […]

> 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?

I thought I understood Guido's explanation but maybe I missed something.

Let C be a class, maybe defined by a class statement or maybe a builtin
like "int".  You can make an instance of C the usual way:

   x = C()

And you can have a type annotation that says function f expects an
arg that is an instance of C:

   def f(x : C) -> int: ...

You might alternatively write a function whose arg must be either an int
or a string:

   def f(s : Union[int, str]) -> int : ...

or (I think, I haven't tried it) you can equivalently bind that type to
a variable:

   T = Union[int, str]
   def f(s : T) -> int : ...

The point here is that T is a type but it is not a class.  You can't
instantiate T by saying

   x = T()

and expecting to get back some value that is (indeterminately) an int or
a string.

That is, there's stuff (like instantiation) that you can do with types
that happen to be classes, but there are also types that aren't classes.

[toc] | [prev] | [next] | [standalone]


#108589 — Re: Distinction between “class” and “type”

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2016-05-13 20:24 +1200
SubjectRe: Distinction between “class” and “type”
Message-ID<dplhacFftlqU1@mid.individual.net>
In reply to#108586
Paul Rubin wrote:
> You can't instantiate T by saying
> 
>    x = T()
> 
> and expecting to get back some value that is (indeterminately) an int or
> a string.

Unless it's Python 6000 running on a quantum computer...

-- 
Greg

[toc] | [prev] | [next] | [standalone]


#108631

FromSteven D'Aprano <steve@pearwood.info>
Date2016-05-14 15:05 +1000
Message-ID<5736b212$0$1587$c3e8da3$5496439d@news.astraweb.com>
In reply to#108578
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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web