From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 38F2CBB84 for ; Mon, 8 May 2006 05:18:00 +0200 (CEST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k483Hx2w011041 for ; Mon, 8 May 2006 05:17:59 +0200 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 FAA04890 for ; Mon, 8 May 2006 05:17:58 +0200 (MET DST) Received: from kurims.kurims.kyoto-u.ac.jp (kurims.kurims.kyoto-u.ac.jp [130.54.16.1]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k483Hu4o011036 for ; Mon, 8 May 2006 05:17:57 +0200 Received: from localhost (suiren [130.54.16.25]) by kurims.kurims.kyoto-u.ac.jp (8.13.6/8.13.6) with ESMTP id k483HkZq024317; Mon, 8 May 2006 12:17:47 +0900 (JST) Date: Mon, 08 May 2006 12:17:43 +0900 (JST) Message-Id: <20060508.121743.65190532.garrigue@math.nagoya-u.ac.jp> To: david.baelde@ens-lyon.org Cc: caml-list@inria.fr Subject: Re: [Caml-list] OO design From: Jacques Garrigue In-Reply-To: <53c655920605050235k64e70333je8df813239ea3c53@mail.gmail.com> References: <53c655920605050235k64e70333je8df813239ea3c53@mail.gmail.com> X-Mailer: Mew version 4.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Miltered: at nez-perce with ID 445EB867.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at nez-perce with ID 445EB864.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; overriding:01 ocaml:01 ocaml:01 subtyping:01 subtyping:01 modular:01 caml-list:01 behaviour:01 functions:01 define:01 jacques:01 jacques:01 defined:02 objects:02 objects:02 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.3 From: "David Baelde" > I'm no OO guru, so my question may be irrelevant, or there just might > not be an answer, which wouldn't hurt.. > > Let's say that I have a base class, with some kind of activation > procedure: anybody wanting to use the class must call #enter before, > and then call #leave for releasing. Internally, the methods #do_enter > and #do_leave are called respectively at the first #enter and last > #leave. > > Nobody should call the #do_* directly, and I'd also like to make sure > the #enter and #leave are never overriden, since their behaviour is > important and actually much more complex than what I said. > > I could just rely on the user who derives my base class, but let's see > what we can do. First the #do_* should be made private, so they can be > defined in the derived classes, but never called from the outside. To > avoid the overriding of #enter and #leave the only solution seems to > make them normal functions instead of methods. But then how could > #enter call #do_enter ? I tried to first define the class with public > #enter and make that method private in the interface, but OCaml told > me that was impossible. I would be tempted to say: there is no answer. Ocaml objects are not about enforcing protocols, but about allowing inheritance and structural subtyping, and this does not fit well with your problem. There are many things you can try to make it harder to derive incorrect classes, but basically if the user wants to do it, he can. Yet, since it seems that you are already relying on the (library) programmer to write correct code for the #do_* methods, another point of view might be that you just want to make sure that only the final user of objects cannot break things. Then the technique described in other answers make sense, for instance prohibiting inheritance from an already completed class. An even stronger protection is to make object types private. This way you are sure than nobody can forge an object of the same type, and you can even hide public methods if you wish. But you loose inheritance. See the object example in my paper on private rows about how to do this. Combining structural subtyping and modular privacy would introduce a lot extra complexity in the type system. Jacques Garrigue