From: Don Syme <firstname.lastname@example.org>
To: "'Markus Mottl'" <email@example.com>
Subject: RE: Classes: when and where? (long) (was: looking for a nail)
Date: Mon, 1 Feb 1999 04:48:15 -0800
Thanks Markus. I think I can buy classes as a structuring device to
encapsulate mutable state, as you say, rather than as an abstraction device.
That is, classes can indeed be effectively employed to create "components",
whereas the utility of subtyping to create "generic components" is not so
clear. I also agree that modules are not a terribly effective structuring
device when hiding mutable state. I might use records of closures (as in the
Format library), but I would also consider using classes. Certainly many
C++ and Java libraries benefit from this kind of use.
Beyond this, I'm aware that there are generic components/abstractions that
can be represented in object calculii that can't be represented conveniently
in the core of Ocaml, and I'm still willing to be convinced of the practical
utility of such abstractions. I think examples may come, especially when we
try to express complex APIs such as those for existing windowing libraries,
but until then I feel the jury is out. (IMHO, given the contorted nature of
many OO-based attempts at abstraction, one might feel the jury could have
given a preliminary verdict some time ago ;-) )
On the question of project failures: I would certainly blame the failure
and/or slow-progress of several projects I've seen on the mis-application of
OO design techniques, in particular on the over use of inheritance and
subtyping as an abstraction technique, and the over use of abstraction in
general. I believe this represents a balanced assessment rather than a
position based on dogma, since it was also the opinion of some of those
involved in the project, after the fact. (I was just an observer). Other
people, perhaps, can report brilliant success in the application of these
abstraction techniques - I'd be pleased to have my opinions changed!
At the lab: At home:
Microsoft Research Cambridge 11 John St
St George House CB1 1DT
Cambridge, CB2 3NH, UK
Ph: +44 (0) 1223 744797 Ph: +44 (0) 1223 722244
"You've been chosen as an extra in the movie
adaptation of the sequel to your life" -- Pavement, Shady Lane
> As it seems, you see classes just as a (bad) form of abstraction. But
> please don't forget their origin and what they were actually
> invented for:
> they were specifically invented to encapsulate overwriteable (mutable)
> values together with methods that manipulate their state. I think that
> they appear more natural in this respect than modules.
> Then, in modules you have to explicitly match values so as to extract
> components to which you can apply functions later on. You
> have to manage
> the whole state (or, if not mutable, value) even if you want to change
> just a very small component. This is not necessary in objects, because
> they "know" of what they consist.
> Just count the times, how often you have to write "_" for unnecessary
> parameters when manipulating values in modules. This is often not very
> > Personally, I think the apparent preference of OCaml users
> to stick with the
> > basic language may be telling - or have I misjudged this? Comments
> > welcome!
> > > There is probably hardly any
> > > program, where
> > > you wouldn't need such constructs.
> > In summary, I think my point is that there are many
> programs (but not all -
> > I don't want to be dogmatic about this) where the
> application of class based
> > abstraction techniques is inappropriate. For example, IMHO
> no compiler I've
> > seen would benefit, nor any symbolic computation system,
> nor any module in
> > the basic OCaml library apart from, perhaps, the Format library.
> You are definitely wrong - at least in the rather symbolic area I
> have to program, I find it much more natural to think in objects than
> in modules. Take, for example, direct graphs (yes, I know
> purely functional, mathematically appealing, even efficient and short
> but still not very intuitiv implementation of graph algorithms):
> Imagine a set of programs that share subprograms (i.e.
> subgraphs). If I
> want to traverse such structures, evaluate meaning, change
> the semantics
> of "objects", apply abstraction operators to subtrees
> (better: subgraphs),
> then I really prefer OO over a normal module system. It is just a more
> *natural* way to reason about it - at least to me.
> That you can do the same with modules does not necessarily mean that
> reasoning about such structures with modules is as intuitiv.
> I hope you see my point: I don't use OO to build huge inheritance
> hierarchies (I hate those). I even don't care too much, whether my
> classes are fully reusable (maximally abstract). All I want to have
> is a means of abstraction that reflects the way I think. And sometimes
> (not always), objects fit better into this scheme.
> Take a look at e.g. Jukka Paakki's paper in ACM Computing Surveys,
> Vol. 27, No. 2, June 1995:
> There he compares different paradigms in implementing languages via
> attribute grammars. One can also define those in terms of "modules" or
> "classes". To me the most concise, flexible and extendible
> example is the
> OO one. Maybe because its form of abstraction better fits the problem
> of specifying the semantics of a language (at least: via attribute
> Anyway, don't say without true motivation that compilers (here:
> compiler-compilers) cannot profit from this paradigm. It's simply
> not true.
> > > Imagine that all basic types were classes and all of them
> > > would support
> > > a method e.g. "print".
> > All very well, but this is, after all, imaginary. The
> runtime cost of
> > supporting a dictionary of methods for basic types is just
> too high (though
> > I guess Haskell manages it via type classes).
> No, this has nothing to do with runtime speed. Wherever you
> can resolve
> the exact type statically, you can generate the same code (or
> at least: if
> the compiler is clever enough). This is not a matter of
> - it is a matter of compilation. And where it is not possible
> to resolve
> at compile time, without objects you would have to use sum
> types anyway -
> but explicitely whereas this is handled implicitely with objects!
> Best regards,
> Markus Mottl, firstname.lastname@example.org,
This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:19 MET