From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id LAA22295 for caml-redistribution; Wed, 3 Feb 1999 11:55:43 +0100 (MET) 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 BAA09215 for ; Sat, 30 Jan 1999 01:17:29 +0100 (MET) Received: from miss.wu-wien.ac.at (miss.wu-wien.ac.at [137.208.107.17]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id BAA15941 for ; Sat, 30 Jan 1999 01:17:23 +0100 (MET) Received: (from mottl@localhost) by miss.wu-wien.ac.at (8.9.0/8.9.0) id BAA09397; Sat, 30 Jan 1999 01:17:21 +0100 (MET) From: Markus Mottl Message-Id: <199901300017.BAA09397@miss.wu-wien.ac.at> Subject: Re: Classes: when and where? (long) (was: looking for a nail) To: dsyme@microsoft.com (Don Syme) Date: Sat, 30 Jan 1999 01:17:21 +0100 (MET) Cc: caml-list@inria.fr (OCAML) In-Reply-To: <39ADCF833E74D111A2D700805F1951EF0F00B94C@RED-MSG-06> from "Don Syme" at Jan 29, 99 10:32:01 am X-Mailer: ELM [version 2.4 PL21] MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Sender: weis > I've used a few object systems, and I agree there are certainly abstractions > you can express with classes that can't be expressed in basic OCaml. My > question is more this: what do people reckon is a sensible way of deciding > when to use class based abstraction? Having witnessed several OO projects > sink into a morass of unnecessary inheritance hierarchies (and this with > very intelligent people on the design teams), it's hard to believe the > devices should be used indiscriminately. This is also a matter of the language - I am not sure, what kind of projects you mean, but if it's not OCAML, it might be that other reasons account for the failure (and unnecessary inheritance hierarchies are just the symptom). One shouldn't forget that modules can also be used to restrict access to classes / class interfaces. I think in combination they can be very powerful. > I think it would be useful if ultimately the OCaml manual included some > discussion on this topic, as experience is gained. In all I've seen very > few balanced assessments of the value of using classes as an abstraction > device. O'Caml seems like an excellent place for making such an assessment > because it's possible to compare solutions side by side, without resorting > to the old fashioned rhetoric about the essential beauty of the lambda > calculus or the purity of OO. ;-) Just to make sure you know: I am not an OO fetishist. But there are some applications, where I think they are a very helpful extension. [lengthy abstraction discussion snipped] 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 readable/intuitiv. > 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 Launchbury's 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 grammars). 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 language/paradigm - 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 -- Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl