The type/object distinction and possible synthesis of OOP andimperative programming languages

Discussion in 'Python' started by Mark Janssen, Apr 15, 2013.

  1. Mark Janssen

    Mark Janssen Guest

    Hello,

    I'm new to the list and hoping this might be the right place to
    introduce something that has provoked a bit of an argument in my
    programming community.

    I'm from the Python programming community. Python is an "interpreted"
    language. Since 2001, Python's has migrated towards a "pure" Object
    model (ref: http://www.python.org/download/releases/2.2/descrintro/).
    Prior to then, it had both types and classes and these types were
    anchored to the underlying C code and the machine/hardware
    architecture itself. After the 2001 "type/class unification" , it
    went towards Alan Kay's ideal of "everything is an object". From
    then, every user-defined class inherited from the abstract Object,
    rooted in nothing but a pure abstract ideal. The parser, lexer, and
    such spin these abstrations into something that can be run on the
    actual hardware.

    As a contrast, this is very distinct from C++, where everything is
    concretely rooted in the language's type model which in *itself* is
    rooted (from it's long history) in the CPU architecture. The STL,
    for example, has many Container types, but each of them requires using
    a single concrete type for homogenous containers or uses machine
    pointers to hold arbitrary items in heterogeneous containers (caveat:
    I haven't programmed in C++ for a long time, so it's possible this
    might not be correct anymore).

    My question is: Is there something in the Computer Science literature
    that has noticed this distinction/development in programming language
    design and history?

    It's very significant to me, because as languages went higher and
    higher to this pure OOP model, the programmer+data ecosystem tended
    towards very personal object hierarchies because now the hardware no
    longer formed a common basis of interaction (note also, OOPs promise
    of re-usable code never materialized).

    It's not unlike LISP, where the power of its general language
    architecture tended towards hyperpersonal mini macro languages --
    making it hardly used, in practice, though it was and is so powerful,
    in theory.

    That all being said, the thrust of this whole effort is to possibly
    advance Computer Science and language design, because in-between the
    purely concrete "object" architecture of the imperative programming
    languages and the purely abstract object architecture of
    object-oriented programming languages is a possible middle ground that
    could unite them all.

    Thank you for your time.

    Mark Janssen
    Tacoma, Washington
    Mark Janssen, Apr 15, 2013
    #1
    1. Advertising

  2. On Sun, 14 Apr 2013 20:48:05 -0700, Mark Janssen wrote:

    > Hello,
    >
    > I'm new to the list and hoping this might be the right place to
    > introduce something that has provoked a bit of an argument in my
    > programming community.
    >
    > I'm from the Python programming community. Python is an "interpreted"
    > language. Since 2001, Python's has migrated towards a "pure" Object
    > model (ref: http://www.python.org/download/releases/2.2/descrintro/).
    > Prior to then, it had both types and classes and these types were
    > anchored to the underlying C code and the machine/hardware architecture
    > itself.



    Incorrect.

    Python's data model has always been 100% object oriented. Prior to the
    "class/type" unification, it simply had *two distinct* implementations of
    objects: types, which were written in C, and classes, which were written
    in Python.

    After unification, the two kinds of object were no longer entirely
    distinct -- you could then subclass types in Python code, using the same
    "class" keyword as you would use for a pure-Python class.

    And starting with Python 3, the last vestiges of the distinction have
    disappeared. Now, "class" and "type" are mere synonyms. Both built-in
    types and custom classes use the same mechanism.


    > After the 2001 "type/class unification" , it went towards Alan
    > Kay's ideal of "everything is an object". From then, every user-defined
    > class inherited from the abstract Object, rooted in nothing but a pure
    > abstract ideal.


    Incorrect. In Python 2.7:


    py> class AClass:
    .... pass
    ....
    py> issubclass(AClass, object)
    False



    --
    Steven
    Steven D'Aprano, Apr 15, 2013
    #2
    1. Advertising

  3. Op 15-04-13 12:11, Steven D'Aprano schreef:

    >
    > Python's data model has always been 100% object oriented. Prior to the
    > "class/type" unification, it simply had *two distinct* implementations of
    > objects: types, which were written in C, and classes, which were written
    > in Python.
    >
    > After unification, the two kinds of object were no longer entirely
    > distinct -- you could then subclass types in Python code, using the same
    > "class" keyword as you would use for a pure-Python class.
    >
    > And starting with Python 3, the last vestiges of the distinction have
    > disappeared. Now, "class" and "type" are mere synonyms. Both built-in
    > types and custom classes use the same mechanism.


    I had gotten my hopes up after reading this but then I tried:


    $ python3
    Python 3.2.3 (default, Feb 20 2013, 17:02:41)
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> class vslice (slice):

    .... pass
    ....
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: type 'slice' is not an acceptable base type


    It seems types and classes are still not mere synonyms.
    Antoon Pardon, Apr 15, 2013
    #3
  4. Mark Janssen

    Dave Angel Guest

    On 04/15/2013 01:43 PM, Antoon Pardon wrote:
    > Op 15-04-13 12:11, Steven D'Aprano schreef:
    >
    >>
    >> Python's data model has always been 100% object oriented. Prior to the
    >> "class/type" unification, it simply had *two distinct* implementations of
    >> objects: types, which were written in C, and classes, which were written
    >> in Python.
    >>
    >> After unification, the two kinds of object were no longer entirely
    >> distinct -- you could then subclass types in Python code, using the same
    >> "class" keyword as you would use for a pure-Python class.
    >>
    >> And starting with Python 3, the last vestiges of the distinction have
    >> disappeared. Now, "class" and "type" are mere synonyms. Both built-in
    >> types and custom classes use the same mechanism.

    >
    > I had gotten my hopes up after reading this but then I tried:
    >
    >
    > $ python3
    > Python 3.2.3 (default, Feb 20 2013, 17:02:41)
    > [GCC 4.7.2] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.
    > >>> class vslice (slice):

    > ... pass
    > ...
    > Traceback (most recent call last):
    > File "<stdin>", line 1, in <module>
    > TypeError: type 'slice' is not an acceptable base type
    >
    >
    > It seems types and classes are still not mere synonyms.


    No, it seems you're trying to use an internal detail as though it were a
    supported feature.

    From page:
    http://docs.python.org/3.3/reference/datamodel.html#types

    """Internal types
    A few types used internally by the interpreter are exposed to the user.
    Their definitions may change with future versions of the interpreter,
    but they are mentioned here for completeness.
    """


    --
    DaveA
    Dave Angel, Apr 15, 2013
    #4
  5. Mark Janssen

    Rotwang Guest

    On 15/04/2013 22:13, Dave Angel wrote:
    > On 04/15/2013 01:43 PM, Antoon Pardon wrote:
    >> [...]
    >>
    >> I had gotten my hopes up after reading this but then I tried:
    >>
    >>
    >> $ python3
    >> Python 3.2.3 (default, Feb 20 2013, 17:02:41)
    >> [GCC 4.7.2] on linux2
    >> Type "help", "copyright", "credits" or "license" for more information.
    >> >>> class vslice (slice):

    >> ... pass
    >> ...
    >> Traceback (most recent call last):
    >> File "<stdin>", line 1, in <module>
    >> TypeError: type 'slice' is not an acceptable base type
    >>
    >>
    >> It seems types and classes are still not mere synonyms.

    >
    > No, it seems you're trying to use an internal detail as though it were a
    > supported feature.
    >
    > From page:
    > http://docs.python.org/3.3/reference/datamodel.html#types
    >
    > """Internal types
    > A few types used internally by the interpreter are exposed to the user.
    > Their definitions may change with future versions of the interpreter,
    > but they are mentioned here for completeness.
    > """


    To be fair, one can't do this either:

    Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64
    bit (AMD64)] on win32
    Type "copyright", "credits" or "license()" for more information.
    >>> class C(type(lambda: None)):

    pass

    Traceback (most recent call last):
    File "<pyshell#2>", line 1, in <module>
    class C(type(lambda: None)):
    TypeError: type 'function' is not an acceptable base type


    and I don't think that FunctionType would be considered an "internal
    detail", would it? Not that I'd cite the fact that not all types can be
    inherited from as evidence that types and classes are not synonyms, mind.
    Rotwang, Apr 15, 2013
    #5
  6. On Tue, Apr 16, 2013 at 8:12 AM, Rotwang <> wrote:
    > Traceback (most recent call last):
    > File "<pyshell#2>", line 1, in <module>
    > class C(type(lambda: None)):
    > TypeError: type 'function' is not an acceptable base type
    >
    >
    > and I don't think that FunctionType would be considered an "internal
    > detail", would it? Not that I'd cite the fact that not all types can be
    > inherited from as evidence that types and classes are not synonyms, mind.


    Actually, I'm not sure how you'd go about inheriting from a function.
    Why not just create a bare class, then assign its __call__ to be the
    function you're inheriting from?

    ChrisA
    Chris Angelico, Apr 15, 2013
    #6
  7. Mark Janssen

    Rotwang Guest

    On 15/04/2013 23:32, Chris Angelico wrote:
    > On Tue, Apr 16, 2013 at 8:12 AM, Rotwang <> wrote:
    >> Traceback (most recent call last):
    >> File "<pyshell#2>", line 1, in <module>
    >> class C(type(lambda: None)):
    >> TypeError: type 'function' is not an acceptable base type
    >>
    >>
    >> and I don't think that FunctionType would be considered an "internal
    >> detail", would it? Not that I'd cite the fact that not all types can be
    >> inherited from as evidence that types and classes are not synonyms, mind.

    >
    > Actually, I'm not sure how you'd go about inheriting from a function.
    > Why not just create a bare class, then assign its __call__ to be the
    > function you're inheriting from?


    No idea. I wasn't suggesting that trying to inherit from FunctionType
    was a sensible thing to do; I was merely pointing out that slice's
    status as an internal feature was not IMO relevant to the point that
    Antoon was making.
    Rotwang, Apr 15, 2013
    #7
  8. On 4/15/2013 1:43 PM, Antoon Pardon wrote:

    > $ python3
    > Python 3.2.3 (default, Feb 20 2013, 17:02:41)
    > [GCC 4.7.2] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.
    > >>> class vslice (slice):

    > ... pass
    > ...
    > Traceback (most recent call last):
    > File "<stdin>", line 1, in <module>
    > TypeError: type 'slice' is not an acceptable base type
    >
    >
    > It seems types and classes are still not mere synonyms.


    Some builtin classes cannot be subclassed. There is an issue to document
    which better. That does not mean that it is not a class.
    Terry Jan Reedy, Apr 16, 2013
    #8
  9. On Mon, 15 Apr 2013 19:43:32 +0200, Antoon Pardon wrote:

    > Op 15-04-13 12:11, Steven D'Aprano schreef:
    >
    >
    >> Python's data model has always been 100% object oriented. Prior to the
    >> "class/type" unification, it simply had *two distinct* implementations
    >> of objects: types, which were written in C, and classes, which were
    >> written in Python.
    >>
    >> After unification, the two kinds of object were no longer entirely
    >> distinct -- you could then subclass types in Python code, using the
    >> same "class" keyword as you would use for a pure-Python class.
    >>
    >> And starting with Python 3, the last vestiges of the distinction have
    >> disappeared. Now, "class" and "type" are mere synonyms. Both built-in
    >> types and custom classes use the same mechanism.

    >
    > I had gotten my hopes up after reading this but then I tried:
    >
    >
    > $ python3
    > Python 3.2.3 (default, Feb 20 2013, 17:02:41) [GCC 4.7.2] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.
    > >>> class vslice (slice):

    > ... pass
    > ...
    > Traceback (most recent call last):
    > File "<stdin>", line 1, in <module>
    > TypeError: type 'slice' is not an acceptable base type
    >
    >
    > It seems types and classes are still not mere synonyms.



    You are misinterpreting what you are reading. The mere fact that
    something cannot be subclassed doesn't mean anything. That's just a
    restriction put on the class by the implementation. It's not even clear
    that it is a guaranteed language restriction or a mere accident of
    implementation. With a bit of metaclass trickery, I could equally create
    a pure-Python class that cannot be easily subclassed.

    The proof that types and classes are the same in Python 3 is simple:

    py> class C:
    .... pass
    ....
    py> type(C) is type(int) is type(type) is type
    True

    The type of the pure-Python class is type itself.

    However, even this can be bypassed, using a metaclass!

    py> class D(metaclass=Meta):
    .... pass
    ....
    py> type(D) is type
    False
    py> issubclass(type(D), type)
    True


    So when using a metaclass, the type of the class is not necessarily type
    itself, but it will be a subclass of type.

    This does not hold in Python 2.x, not for old-style "classic" classes.
    Classic classes are in a world of their own, distinct from types:

    # Python 2
    py> class C:
    .... pass
    ....
    py> type(C)
    <type 'classobj'>
    py> issubclass(type(C), type)
    False



    In Python 3, we can expect these two conditions to always hold:

    * all instances are instances of object;

    * all classes are instances of type.


    Notice that this implies that type and object are circularly defined:
    object, being a class, is an instance of type, but type, being an object,
    is an instance of object:

    py> isinstance(type, object)
    True
    py> isinstance(object, type)
    True



    These two conditions even apply to unsubclassable objects like slice:

    py> isinstance(slice(1, 5, 2), object)
    True
    py> isinstance(slice, type)
    True



    --
    Steven
    Steven D'Aprano, Apr 16, 2013
    #9
  10. On Mon, 15 Apr 2013 20:52:58 -0400, Terry Jan Reedy wrote:

    > On 4/15/2013 1:43 PM, Antoon Pardon wrote:
    >
    >> $ python3
    >> Python 3.2.3 (default, Feb 20 2013, 17:02:41) [GCC 4.7.2] on linux2
    >> Type "help", "copyright", "credits" or "license" for more information.
    >> >>> class vslice (slice):

    >> ... pass
    >> ...
    >> Traceback (most recent call last):
    >> File "<stdin>", line 1, in <module>
    >> TypeError: type 'slice' is not an acceptable base type
    >>
    >>
    >> It seems types and classes are still not mere synonyms.

    >
    > Some builtin classes cannot be subclassed. There is an issue to document
    > which better. That does not mean that it is not a class.



    I think it is also important to document whether that is a language
    feature, or a mere restriction of the implementation. There is an
    important distinction to be made between:

    "In CPython, you cannot subclass slice or FunctionType. Other Pythons may
    have more, or fewer, restrictions."

    and:

    "No language that calls itself Python is permitted to allow slice and
    FunctionType to be subclassable."


    If I had a say in this, I would vote for the first case, with the
    possible exception of documented singleton types like NoneType and bool.



    --
    Steven
    Steven D'Aprano, Apr 16, 2013
    #10
  11. On 4/15/2013 10:32 PM, Steven D'Aprano wrote:
    > On Mon, 15 Apr 2013 20:52:58 -0400, Terry Jan Reedy wrote:


    >> Some builtin classes cannot be subclassed. There is an issue to document
    >> which better. That does not mean that it is not a class.

    >
    >
    > I think it is also important to document whether that is a language
    > feature, or a mere restriction of the implementation. There is an
    > important distinction to be made between:
    >
    > "In CPython, you cannot subclass slice or FunctionType. Other Pythons may
    > have more, or fewer, restrictions."
    >
    > and:
    >
    > "No language that calls itself Python is permitted to allow slice and
    > FunctionType to be subclassable."
    >
    >
    > If I had a say in this, I would vote for the first case, with the
    > possible exception of documented singleton types like NoneType and bool.


    I will keep the above in mind if I write or review a patch. here are 4
    non-subclassable builtin classes. Two are already documented. Bool in
    one, forget which other. I believe it was recently decided to leave the
    other two as is given the absence of any practical use case.
    Terry Jan Reedy, Apr 16, 2013
    #11
  12. Mark Janssen

    Ian Kelly Guest

    On Mon, Apr 15, 2013 at 9:17 PM, Terry Jan Reedy <> wrote:
    > I will keep the above in mind if I write or review a patch. here are 4
    > non-subclassable builtin classes. Two are already documented. Bool in one,
    > forget which other. I believe it was recently decided to leave the other two
    > as is given the absence of any practical use case.


    The four are bool, NoneType, slice and ellipsis, I believe.
    Ian Kelly, Apr 16, 2013
    #12
  13. Mark Janssen

    rusi Guest

    On Apr 16, 7:32 am, Steven D'Aprano <steve
    > wrote:
    >
    > If I had a say in this, I would vote for the first case, with the
    > possible exception of documented singleton types like NoneType and bool.


    How is bool a singleton type?
    rusi, Apr 16, 2013
    #13
  14. On Mon, 15 Apr 2013 21:56:12 -0700, rusi wrote:

    > On Apr 16, 7:32 am, Steven D'Aprano <steve
    > > wrote:
    >>
    >> If I had a say in this, I would vote for the first case, with the
    >> possible exception of documented singleton types like NoneType and
    >> bool.

    >
    > How is bool a singleton type?



    A doubleton, then.


    The point being, GvR declared that bool should guarantee the invariant
    that True and False are the only instances of bool, and if you can
    subclass it, either that invariant is violated, or you can't instantiate
    the subclass.



    --
    Steven
    Steven D'Aprano, Apr 16, 2013
    #14
  15. zipheræ–¼ 2013å¹´4月15日星期一UTC+8上åˆ11時48分05秒寫é“:
    > Hello,
    >
    >
    >
    > I'm new to the list and hoping this might be the right place to
    >
    > introduce something that has provoked a bit of an argument in my
    >
    > programming community.


    I'll state about my opinions about the imperative and
    non-imperative part.

    If the finite stack depth is used instead of the infinite one,
    then the auto local variables of the imperative part
    can be implemented quite safe and cheap or at least
    self-recoverable from a stack overflow event.

    This can save a lot burdens in the GC part in an imperative
    language.
    88888 Dihedral, Apr 16, 2013
    #15
  16. zipheræ–¼ 2013å¹´4月15日星期一UTC+8上åˆ11時48分05秒寫é“:
    > Hello,
    >
    >
    >
    > I'm new to the list and hoping this might be the right place to
    >
    > introduce something that has provoked a bit of an argument in my
    >
    > programming community.


    I'll state about my opinions about the imperative and
    non-imperative part.

    If the finite stack depth is used instead of the infinite one,
    then the auto local variables of the imperative part
    can be implemented quite safe and cheap or at least
    self-recoverable from a stack overflow event.

    This can save a lot burdens in the GC part in an imperative
    language.
    88888 Dihedral, Apr 16, 2013
    #16
  17. On 16.04.13 07:46, Ian Kelly wrote:
    > On Mon, Apr 15, 2013 at 9:17 PM, Terry Jan Reedy <> wrote:
    >> I will keep the above in mind if I write or review a patch. here are 4
    >> non-subclassable builtin classes. Two are already documented. Bool in one,
    >> forget which other. I believe it was recently decided to leave the other two
    >> as is given the absence of any practical use case.

    >
    > The four are bool, NoneType, slice and ellipsis, I believe.


    >>> import builtins
    >>> for n in dir(builtins):

    .... if type(getattr(builtins, n)) is type:
    .... try:
    .... t = type(n, (getattr(builtins, n),), {})
    .... except TypeError as e:
    .... print(e)
    ....
    type 'bool' is not an acceptable base type
    type 'memoryview' is not an acceptable base type
    type 'range' is not an acceptable base type
    type 'slice' is not an acceptable base type
    Serhiy Storchaka, Apr 16, 2013
    #17
  18. Op 16-04-13 05:17, Terry Jan Reedy schreef:
    > On 4/15/2013 10:32 PM, Steven D'Aprano wrote:
    >> On Mon, 15 Apr 2013 20:52:58 -0400, Terry Jan Reedy wrote:

    >
    >>> Some builtin classes cannot be subclassed. There is an issue to
    >>> document
    >>> which better. That does not mean that it is not a class.

    >>
    >>
    >> I think it is also important to document whether that is a language
    >> feature, or a mere restriction of the implementation. There is an
    >> important distinction to be made between:
    >>
    >> "In CPython, you cannot subclass slice or FunctionType. Other Pythons
    >> may
    >> have more, or fewer, restrictions."
    >>
    >> and:
    >>
    >> "No language that calls itself Python is permitted to allow slice and
    >> FunctionType to be subclassable."
    >>
    >>
    >> If I had a say in this, I would vote for the first case, with the
    >> possible exception of documented singleton types like NoneType and bool.

    >
    > I will keep the above in mind if I write or review a patch. here are 4
    > non-subclassable builtin classes. Two are already documented. Bool in
    > one, forget which other. I believe it was recently decided to leave
    > the other two as is given the absence of any practical use case.


    Why should there be a practical use case here? Since classes are in
    general subclassable, shouldn't you have a reason to not make them so
    instead of people needing to give you a practical use case before you
    treat them as you do most of them?

    I once had an idea of a slice-like class that I would have liked to
    experiment with. As things were I didn't get far because slice not being
    subclassable was a major hurdle in getting it practical. Would the end
    result have been a practical use case? I don't know, I didn't get the
    chance to find out because making a class that looked like a slice
    didn't work either. Python wanted, maybe still wants, a real slice in a
    number of circumstances and not a ducktyped slice-like object.

    Now maybe there are good reasons for slice not being subclassable but
    there not being a practical use case doesn't seem to be one in this case.
    Antoon Pardon, Apr 16, 2013
    #18
  19. On 4/16/2013 5:07 AM, Antoon Pardon wrote:
    > Op 16-04-13 05:17, Terry Jan Reedy schreef:
    >> On 4/15/2013 10:32 PM, Steven D'Aprano wrote:
    >>> On Mon, 15 Apr 2013 20:52:58 -0400, Terry Jan Reedy wrote:

    >>


    >> I will keep the above in mind if I write or review a patch. here are 4
    >> non-subclassable builtin classes. Two are already documented. Bool in
    >> one, forget which other. I believe it was recently decided to leave
    >> the other two as is given the absence of any practical use case.

    >
    > Why should there be a practical use case here?


    As a practical matter, the change is non-trivial. Someone has to be
    motivated to write the patch to enable subclassing, write tests, and
    consider the effect on internal C uses of slice and stdlib Python used
    of slice (type() versus isinstance).

    > Since classes are in general subclassable,


    if written in Python, but not if written in C.

    > I once had an idea of a slice-like class that I would have liked to
    > experiment with.


    Did the idea actually require that instances *be* a slice rather than
    *wrap* a slice?

    --
    Terry Jan Reedy
    Terry Jan Reedy, Apr 16, 2013
    #19
  20. Mark Janssen

    Ethan Furman Guest

    On 04/16/2013 01:25 AM, Serhiy Storchaka wrote:
    > On 16.04.13 07:46, Ian Kelly wrote:
    >> On Mon, Apr 15, 2013 at 9:17 PM, Terry Jan Reedy <> wrote:
    >>> I will keep the above in mind if I write or review a patch. here are 4
    >>> non-subclassable builtin classes. Two are already documented. Bool in one,
    >>> forget which other. I believe it was recently decided to leave the other two
    >>> as is given the absence of any practical use case.

    >>
    >> The four are bool, NoneType, slice and ellipsis, I believe.

    >
    > --> import builtins
    > --> for n in dir(builtins):
    > ... if type(getattr(builtins, n)) is type:
    > ... try:
    > ... t = type(n, (getattr(builtins, n),), {})
    > ... except TypeError as e:
    > ... print(e)
    > ...
    > type 'bool' is not an acceptable base type
    > type 'memoryview' is not an acceptable base type
    > type 'range' is not an acceptable base type
    > type 'slice' is not an acceptable base type


    Well that bumps our count to five then:

    --> NoneType = type(None)
    --> NoneType
    <class 'NoneType'>
    --> class MoreNone(NoneType):
    .... pass
    ....
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: type 'NoneType' is not an acceptable base type

    --
    ~Ethan~
    Ethan Furman, Apr 16, 2013
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page