caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Classes AND Modules?  What's the point?
@ 1999-11-01  9:01 Mark Engelberg
  1999-11-03 23:13 ` William Chesters
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mark Engelberg @ 1999-11-01  9:01 UTC (permalink / raw)
  To: caml-list

I have spent some time this past week looking at OCaml for the first time.
I have no previous experience with ML, but I do have a pretty good
understanding of functional languages in principle.

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.

The problem is that because modules are slightly more powerful, it appears
that the entire standard library is implemented as modules, not classes,
despite the fact that this is supposed to be Object-oriented Caml!  This
doesn't really make sense to me, because it totally hinders your ability to
subclass and extend the default libraries.

This weird coexistence of classes and modules just doesn't make sense to me.
Wouldn't it have made more sense to simply add the concept of inheritance to
modules, rather than define a new "class" construct that supports
inheritance but not all the other features of modules?  Or if the focus is
intended to gradually shift in the direction of classes rather than modules,
shouldn't the standard libraries reflect this?

Can someone please explain?

Thanks,

Mark Engelberg




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Classes AND Modules?  What's the point?
  1999-11-01  9:01 Classes AND Modules? What's the point? Mark Engelberg
@ 1999-11-03 23:13 ` William Chesters
  1999-11-05 10:13 ` Xavier Leroy
  1999-11-05 18:49 ` Francisco Valverde Albacete
  2 siblings, 0 replies; 5+ messages in thread
From: William Chesters @ 1999-11-03 23:13 UTC (permalink / raw)
  To: Mark Engelberg; +Cc: caml-list

Mark Engelberg writes:
 > 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.

   Interestingly, the big difference is that modules are not "first
class values".  You can't pass the whole thing around, along with its
dispatch table, like you can an object.  You can't write

	module type Shape = sig
	  val area: unit -> float
	end

	module Square (Init: sig val side: float end) = struct
	  let side = Init.side
	  let area () = side *. side
	end

	let foo M = M.area ()     (* this isn't allowed *)

	let _ =
	  let module It = Square (struct let side = 50. end)
	  in
	  foo It                  (* nor is this *)

So although you can create modules on the fly with "let module", and
pass their _members_ around, you can't really use the instantiations
conveniently as objects.  There is no way to use modules per se to
achieve class-style polymorphism.

   I have often thought that you could get something very like the
ocaml class system, with similar semantics and implementational
issues, by this kind of route.

 > The problem is that because modules are slightly more powerful, it appears
 > that the entire standard library is implemented as modules, not classes,
 > despite the fact that this is supposed to be Object-oriented Caml!

   IIRC OLabl ships with object versions of some of the libraries.

   Don't forget that object a method invocation is a little slower
than a module function call---I measured fetches from a Hashtbl,
indirected through an object wrapper, about 10% slower than fetches
indirected through a module.  Anyway, object-using programs don't
always necessarily work out prettier than module-based ones.




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Classes AND Modules?  What's the point?
  1999-11-01  9:01 Classes AND Modules? What's the point? Mark Engelberg
  1999-11-03 23:13 ` William Chesters
@ 1999-11-05 10:13 ` Xavier Leroy
  1999-11-05 18:49 ` Francisco Valverde Albacete
  2 siblings, 0 replies; 5+ messages in thread
From: Xavier Leroy @ 1999-11-05 10:13 UTC (permalink / raw)
  To: Mark Engelberg, caml-list

> I have spent some time this past week looking at OCaml for the first time.
> I have no previous experience with ML, but I do have a pretty good
> understanding of functional languages in principle.
> 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.

We are aware of the overlap between classes and modules, although I'm
not sure the overlap is as large as you say.  I gave an invited talk
on this topic at last ICFP; the slides are available from my home page
(http://pauillac.inria.fr/~xleroy/)

> The problem is that because modules are slightly more powerful, it appears
> that the entire standard library is implemented as modules, not classes,
> despite the fact that this is supposed to be Object-oriented Caml!

There are two reasons why the standard library is implemented without
classes.  The historical reason is that the standard library comes
straight from Caml Special Light, the ancestor of OCaml that didn't
have classes and objects yet, but already had objects.

The other reason is that I don't see any module in the standard
library (except perhaps Format) that would really benefit from being
converted into objects and classes.  For many data structures
(hash tables, stacks, etc) the class-based presentation would be no
better than the current module/abstract data type presentation.
For others (sets, maps), the class-based presentation would be less
good, e.g. with less precise static typing.

> This
> doesn't really make sense to me, because it totally hinders your ability to
> subclass and extend the default libraries.

Do you really need to?  What good would it make to subclass hash
tables as opposed to putting a hash table in a field or instance
variable of another datatype or class?  No offense intended, but
programmers with extensive C++/Java background are so used to the
inheritance hammer that they see every problem as a nail.  Inheritance
is great in some cases (I've used it in parts of the native-code
compiler and it was very nice), but in my opinion nearly useless for
simple data structures like those of the OCaml standard library.

> This weird coexistence of classes and modules just doesn't make sense to me.
> Wouldn't it have made more sense to simply add the concept of inheritance to
> modules, rather than define a new "class" construct that supports
> inheritance but not all the other features of modules?

It would make a lot of sense, but it's still an open research issue.
In particular, no-one knows yet how to "add the concept of inheritance
to modules" in a way that really reduces the overlap between classes and
modules.  (See for instance Jérôme Vouillon's paper "Using modules as
classes", http://pauillac.inria.fr/~vouillon/publi/classes.ps.gz)

> Or if the focus is
> intended to gradually shift in the direction of classes rather than modules,
> shouldn't the standard libraries reflect this?

My intention is certainly not to shift away from modules.  The way I
like to think about OCaml is that you have functions, datatypes and
modules for "everyday" programming, and classes and objects for those
programs that need them in an essential way.

- Xavier Leroy



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Classes AND Modules?  What's the point?
  1999-11-01  9:01 Classes AND Modules? What's the point? Mark Engelberg
  1999-11-03 23:13 ` William Chesters
  1999-11-05 10:13 ` Xavier Leroy
@ 1999-11-05 18:49 ` Francisco Valverde Albacete
  1999-11-07 23:31   ` Gerd Stolpmann
  2 siblings, 1 reply; 5+ messages in thread
From: Francisco Valverde Albacete @ 1999-11-05 18:49 UTC (permalink / raw)
  To: Mark Engelberg; +Cc: caml-list

Hi,

[Resumé en Français à la fin]

I have also been wondering at this question and haven't found and answer yet but
I am willing to share a couple of thoughts with you, if you'd like... Read on,
please!

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.

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.

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

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

> The problem is that because modules are slightly more powerful, it appears
> that the entire standard library is implemented as modules, not classes,
> despite the fact that this is supposed to be Object-oriented Caml!  This
> doesn't really make sense to me, because it totally hinders your ability to
> subclass and extend the default libraries.

I was one of the users who missed modules in old CAML and very much like modules
in Ocaml (and Camlight) as a means to structure code and libraries, although I
have been unable yet to obtain such good use out of classes and objects (mainly
because I think I don't understand row polymorphism).

But the point is *I want modules to structure code!*. They are local contexts
whereas classes are not. You still have to define modules to contain your
classes!

> This weird coexistence of classes and modules just doesn't make sense to me.
> Wouldn't it have made more sense to simply add the concept of inheritance to
> modules, rather than define a new "class" construct that supports
> inheritance but not all the other features of modules?  Or if the focus is
> intended to gradually shift in the direction of classes rather than modules,
> shouldn't the standard libraries reflect this?

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

> Can someone please explain?

I wouldn't call this an explanation, but I hope it has come in handy.

[Français dès ici:

Il me semble qu'il faut compare les objects aux types normaux plutôt qu'aux
modules. En vue des developpements en coalgèbres ça peut bien être le cas. Alors
on laisserait les modules comme un mecanisme de modularisation des contextes.]

Regards,

            Francisco Valverde





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Classes AND Modules? What's the point?
  1999-11-05 18:49 ` Francisco Valverde Albacete
@ 1999-11-07 23:31   ` Gerd Stolpmann
  0 siblings, 0 replies; 5+ messages in thread
From: Gerd Stolpmann @ 1999-11-07 23:31 UTC (permalink / raw)
  To: Francisco Valverde Albacete; +Cc: caml-list

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



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1999-11-08 16:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-11-01  9:01 Classes AND Modules? What's the point? Mark Engelberg
1999-11-03 23:13 ` William Chesters
1999-11-05 10:13 ` Xavier Leroy
1999-11-05 18:49 ` Francisco Valverde Albacete
1999-11-07 23:31   ` Gerd Stolpmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).