From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id A3BDABB83 for ; Fri, 25 Aug 2006 13:31:55 +0200 (CEST) Received: from smtp1.adl2.internode.on.net (smtp1.adl2.internode.on.net [203.16.214.181]) by nez-perce.inria.fr (8.13.6/8.13.6) with ESMTP id k7PBVroL010641 for ; Fri, 25 Aug 2006 13:31:54 +0200 Received: from rosella (ppp14-47.lns2.syd7.internode.on.net [59.167.14.47]) by smtp1.adl2.internode.on.net (8.13.6/8.13.5) with ESMTP id k7PBVUdw050295; Fri, 25 Aug 2006 21:01:32 +0930 (CST) (envelope-from skaller@users.sourceforge.net) Subject: Re: [Caml-list] Class/prototype-based OO From: skaller To: david.baelde@ens-lyon.org Cc: Ocaml In-Reply-To: <53c655920608250051x48d81cbagabf8039f0269beee@mail.gmail.com> References: <53c655920608250051x48d81cbagabf8039f0269beee@mail.gmail.com> Content-Type: text/plain Date: Fri, 25 Aug 2006 21:31:30 +1000 Message-Id: <1156505490.20759.354.camel@rosella.wigram> Mime-Version: 1.0 X-Mailer: Evolution 2.6.1 Content-Transfer-Encoding: 7bit X-Miltered: at nez-perce with ID 44EEDFA9.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; subtyping:01 ocaml:01 class-based:01 ocaml:01 trivial:01 structurally:01 axioms:01 abstraction:01 abstraction:01 implements:01 semantically:01 proxies:01 dispatching:01 subtyping:01 gtk:01 On Fri, 2006-08-25 at 09:51 +0200, David Baelde wrote: > Hi list, > > After having had to learn Java, I was annoyed by the lack of subtyping > compared to OCaml. In Java two identical classes with different names > cannot be used identically. I then re-read Wikipedia's articles on > prototype-based [1] and class-based [2] OO. I used to be convinced > that OCaml was cited in the first category. It is not the case, and I > see now that the question is not trivial. > > It is said that prototype-based OO is criticized for being too > dynamic, I believe that OCaml style of OO is an example of static > language having at least the most interesting features of > prototype-based OO. > > Any opinion? Yeah, you're confused. Ocaml isn't using prototypes. Languages like Cecil use prototypes. In this case, you create an object at run time, and make similar objects by cloning the original object. This is entirely unrelated to the difference between classes with nominal (named) typing (C++, Java) and classes with structural typing (Ocaml). There is no doubt whatsoever nominal typing is rubbish :) The reason, trivially, is that any structurally based typing can always be promoted to a nominally typed system by simply adding a phantom nominal type representing the 'name'. On the other hand, structural typing solves a major problem with nominal typing which destroys class based object orientation entirely: the inability to devise new algorithms which use objects satisfying certain axioms -- in other words, an abstraction -- unless the class was derived from, or specified to implement, that particular abstraction when it was designed: class X : public Abstraction { .. in C++. The number of possible interfaces a given class may have is combinatorial in the number of methods, and so it is not tenable to name them all in advance, but if you want to use one NOT named previously, after creating it you have to invade every instance class specification and add a new interface to its base-class or implements list, breaking the open/closed principle on which dynamic dispatch and the very notion of encapsulation central to OO actually rests: class X : public Abstraction, public NewAbstraction { // ^^^^^^^^^^^^^^^^^^^^^^^^ // violation of encapsulation! Thus, from a software engineering viewpoint, nominal typing is not a viable option .. which is one reason programming in Java or C++ using OO sucks. In Ocaml, it works much better because you can actually write algorithms which work with many different types, provided only they support the 'right methods'. You should note structural typing does NOT solve the problem, but it does reduce the problem. It doesn't solve the problem, because methods have names which count in the class signature. It's the old problem all over again, but at a lower level. And even if this weren't so it STILL wouldn't solve the problem, because more than one data type can represent the same thing .. so even the types may be semantically, but not physically, equivalent: int * float // a pair of an int and a float float * int // woops, ANOTHER type, same information! In ALL these cases *including* the nominal typing situation there is a universal solution: wrapping/proxies/forwarding functions/delegation/mapping as you want to call it, in which you build the required interface, and implement its methods by dispatching to an object of the 'wrong' type. However this is not only messy .. particularly in C++ since it has no garbage collection .. it also tends to destroy subtyping. There is a point where all this housekeeping is so unreliable and difficult you'd be better off with dynamic typing, such as that provided by prototype based OO, or other kinds of object systems such as that used by Python (which is more or less prototype based but actually uses classes rather than cloning prototypes). The boundary is probably close to the amazing feat of constructing an Ocaml binding for GTK. -- John Skaller Felix, successor to C++: http://felix.sf.net