[TYPES] The type/object distinction and possible synthesis of OOP and imperative programming languages
jonathan.aldrich at cs.cmu.edu
Fri Apr 19 11:38:23 EDT 2013
I'll respond to both Jason and Greg, below.
Jason Wilkins wrote:
> Thanks Jonathan for the information. I was not completely confident
> that I was correct about objects and side effects, but almost every
> definition of an "object" I've read heavily implies that they contain
> state. How else can you bind state and methods together if there is
> no state ;-) Perhaps the common definition is misleading.
Yes, it's probably more accurate to say that objects bind data and
behavior (methods) together, and provide a procedural (method-based)
interface to the abstraction. The data is often mutable, but not always.
Greg Morrisett wrote:
> I fail to see what dynamic dispatch has to do with subtype
> polymorphism. They are completely orthogonal. (And even
> dynamic dispatch is an abused term.)
Ok, you're right to make a distinction between these; dynamic dispatch
is the more fundamental concept with respect to objects. But subtype
polymorphism is related, at least in practice: see below.
> Objects are a degenerate
> case of first-class modules (ADTs in Uday's terms.)
In Cook's essay, "an object is a value exporting a procedural interface
to data or behavior," which is consistent with my understanding of the
term dynamic dispatch. I agree that an object is equivalent to a
first-class module that exports a purely procedural interface.
I disagree that ADTs are equivalent to either modules or objects. Read
Cook's essay for a discussion of the latter; for the former, consider
that it's often useful to define more than one ADT in a single module.
> true that it's natural to couple this with sub-type polymorphism.
> But it's also natural to couple this (a la OCaml's object system)
> with e.g., row polymorphism.
> I do agree that the abstraction mechanisms used have little
> or nothing to do with state and identity, which is also
> typically confused with the whole "OO" mantra. It's perfectly
> reasonable to do value-oriented programming with first
> class ADTs. Happens in both Haskell and OCaml all the time.
True, but type classes (which is what I assume you mean by first-class
ADTs in Haskell) use type abstraction and therefore do not directly give
you the properties you get from objects.
A critical property of objects, which is used architecturally in many OO
systems, is support for heterogeneous data structures: e.g. putting
several different implementations of an abstraction into a list. You
can do this is Haskell only through a "slightly clumsy" encoding that
wraps a type class in another data structure, thereby existentially
quantifying over the type class used. See "Simulating objects" near the
end of Simon Peyton Jones's talk:
Interestingly, if you use pure row polymorphism to hide certain fields
of a record, the identity of those fields is still carried (abstractly)
by the row variable. In this sense row polymorphism is also a form of
type abstraction. With pure row polymorphism, just as with type classes
in Haskell, you can't implement heterogeneous data structures unless you
pack the row variable in an existential.
OCaml supports objects better than Haskell because it makes
existentially quantifying over the row variable easy--and because OCaml
supports subtyping between object/row types! Thus there's an argument
that subtype polymorphism is more closely tied to objects than row
polymorphism. But dispatch, or more precisely "a value exporting a
procedural interface to data or behavior" is more fundamental.
More information about the Types-list