Re: Classes AND Modules? What's the point?

From: Gerd Stolpmann (Gerd.Stolpmann@darmstadt.netsurf.de)
Date: Mon Nov 08 1999 - 00:31:53 MET


From: Gerd Stolpmann <Gerd.Stolpmann@darmstadt.netsurf.de>
To: "Francisco Valverde Albacete" <fva@tsc.uc3m.es>
Subject: Re: Classes AND Modules? What's the point?
Date: Mon, 8 Nov 1999 00:31:53 +0100
Message-Id: <99110801431700.18117@ice>

On Fri, 05 Nov 1999, Francisco Valverde Albacete wrote:
>Mark Engelberg wrote:
>
>> The thing that confuses me the most about OCaml is that there is a huge
>> overlap between the functionality of classes and modules, with a couple of
>> subtle differences. Classes offer inheritance which is extremely useful,
>> but modules have a little more typing flexibility, the ability to share
>> private data among multiple structures in one package, and the ability to
>> specify compilation units.
>
>Let me explain my prejudices as I used to have them some months ago:
>
>- modules are for functional, stateless Abstract Data Types: you can define the
>main sort of the Type (even polymorphic ones) and add all orbiting sorts you
>need and so forth. You can even define them inductively with data constructors,
>do pattern matching and the sort of niceties you'd expect of functional data
>types and you can define observer functions and de-structors (though you'd call
>them projections or coprojections and whatever)
>
>- classes and objects are for anything resembling *states*: you pass the initial
>state on creation, then mutate and observe it through observers. You have *one*
>constructor through the "new" function, and destruction is done (thank's god) by
>the GC.

I do not think that this is the difference between modules and classes. It is
very simple to encapsulate states in modules, such as

module M =
  struct
    type t =
      { mutable x : t1;
        mutable y : t2;
        ...
      }
     ... functions defined on t ...
  end

If you consider only *one* class or module, a module like M can be used in the
same way as a class with (mutable) instance variables x, y,... .

Furthermore, it is also possible to define functional classes, i.e. instead of
modifying the state of the object the method is defined on, the method returns
a second object which includes the change.

The real difference is that there is a subtyping relation between classes but
not between modules. This simply means that classes can be better if you have
objects/values with a similar but not identical behaviour; in this case you can
try to define the variants as subclasses of a (perhaps abstract) main class.
Note that it is also possible to have a similar effect by a defining a functor
F (A : T) -> B where the parameter A defines the differences of the variants;
but this does not work if the variants needs to be dynamically processed.

On the other hand, modules can hide the details of an implementation; classes
cannot. I think modules really define an abstraction because they generalize
their own implementation, whereas classes are some kind of big "if ... then ..
else" statement which can be used to improve the structure of the program.

>Now, picture trying to set a state on a module (mainly defining some local
>initialized variables) and keep several instances of this state... Nasty & ugly,
>right? That's what we improved in from Camllight to OCaml: nice ways for doing
>stateful things.

See above for a module solution which allows it to have more than one instance
of a set of states.

>Now, picture bundling up an abstraction through a class without resorting to
>modules. You can't even define types! (This used to be so, but maybe it's
>changing in the next release?)

In the "pure" object-oriented languages, defining a class is the only way to
define a new type.

>Also, the name "constructor" doesn't even mean
>the same for types and classes... I can't even imagine doing *everything* with
>classes! A very customizable facility is what with modules (somewhere in the way
>from CAML to Camlight 0.7)
>
>Now, this is my new vision: some algebraic work by a guy called B. Jacobs
>suggests that:
>- "normal" types admit initial algebras as models, their terms are finitely
>generable from constructors and you can prove and define properties by
>structural induction;
>
>- "class" types admit *final coalgebras* as models, they are not finitely
>generable but they are models for infinite structures, you can define them
>co-inductively and prove properties by bisimulation...

I think such theoretical background is helpful to make a typing approach sound
and consistent, but this is not what you think about when you really use the
types in programming. The more interesting point is that classes do not
prescribe anything to their subclasses except the signature of the methods.
This makes classes a very problematic construct; when you program with
classes you need always a concrete idea what the classes are good for. Speaking
more abstract, you need an ad-hoc theory to reduce the number of models. (And
ad-hoc theories can only be enforced by programming discipline!)

>Thus it would seem that (normal) types and classes are natural competitors, and
>modules are left as local contexts to bundle them all up.

What about the operations? The "normal" (data) types only have a set of
standard operations such that one can create and analyze values of these types
in an arbitrary way. In contrast to this, both classes and modules bind data
types and operations on these types together.

>I would still like to see modules as first values (recursion & the like) but
>this seems out of the frontiers of abstract language science for the time being.
>
>And yes!, I'd like inheritance in modules, but this looks as if would not work
>like we are used to with classes (inheriting parts of contexts, overwriting old
>parts?)

Inheritance is not the problem; the class calculus defines that inheritance
means copying the method definitions of the superclass. This part of the class
calculus can be adopted to the module system.

The problem is that (class) inheritance is often used to abbreviate the
definition of a subclass, and what is the purpose of module inheritance?

Gerd

--
----------------------------------------------------------------------------
Gerd Stolpmann      Telefon: +49 6151 997705 (privat)
Viktoriastr. 100             
64293 Darmstadt     EMail:   Gerd.Stolpmann@darmstadt.netsurf.de (privat)
Germany                     
----------------------------------------------------------------------------



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:28 MET