From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: weis Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id RAA26663 for caml-redistribution@pauillac.inria.fr; Mon, 8 Nov 1999 17:32:23 +0100 (MET) Resent-Message-Id: <199911081632.RAA26663@pauillac.inria.fr> Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id BAA22764 for ; Mon, 8 Nov 1999 01:44:15 +0100 (MET) Received: from beach.frankfurt.netsurf.de (beach.frankfurt.netsurf.de [194.64.181.2]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id BAA08501 for ; Mon, 8 Nov 1999 01:44:14 +0100 (MET) Received: from ice.darmstadt.netsurf.de (board-56.darmstadt.netsurf.de [194.163.86.184]) by beach.frankfurt.netsurf.de (8.8.5/8.8.5) with ESMTP id BAA12023; Mon, 8 Nov 1999 01:44:03 +0100 (MET) Received: from localhost (localhost [[UNIX: localhost]]) by ice.darmstadt.netsurf.de (8.9.3/8.9.3) id BAA18270; Mon, 8 Nov 1999 01:43:17 +0100 From: Gerd Stolpmann Reply-To: Gerd.Stolpmann@darmstadt.netsurf.de Organization: privat To: "Francisco Valverde Albacete" Subject: Re: Classes AND Modules? What's the point? Date: Mon, 8 Nov 1999 00:31:53 +0100 X-Mailer: KMail [version 1.0.21] Content-Type: text/plain References: <382326A7.89245BFB@tsc.uc3m.es> Cc: caml-list@inria.fr MIME-Version: 1.0 Message-Id: <99110801431700.18117@ice> Content-Transfer-Encoding: 8bit Resent-From: weis@pauillac.inria.fr Resent-Date: Mon, 8 Nov 1999 17:32:23 +0100 Resent-To: caml-redistribution@pauillac.inria.fr 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 ----------------------------------------------------------------------------