From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id SAA18096 for caml-redistribution; Fri, 13 Sep 1996 18:44:04 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.6.10/8.6.6) with ESMTP id OAA12770 for ; Fri, 13 Sep 1996 14:31:59 +0200 Received: from nef.ens.fr (nef.ens.fr [129.199.96.12]) by concorde.inria.fr (8.7.1/8.7.1) with SMTP id OAA09601 for ; Fri, 13 Sep 1996 14:31:58 +0200 (MET DST) Received: from vedette.ens.fr by nef.ens.fr (5.65c8/ULM-1.0) Id AA08958 ; Fri, 13 Sep 1996 14:31:56 +0200 Date: Fri, 13 Sep 1996 14:31:50 +0200 (MET DST) From: Jerome Vouillon Sender: weis Reply-To: Jerome Vouillon Subject: Re: Closed Objects To: Andrew Conway Cc: caml-list@pauillac.inria.fr In-Reply-To: <199609121922.MAA19250@vegemite.Stanford.EDU> Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII > class virtual runaround () as self : 'a = > virtual null : bool > virtual next : runaround > virtual myself : runaround > end;; > > (* Add a method. This DOESN'T compile in ocaml 1.01, but > did compile in ocaml 1.00. The error message says that it > is closed, but not marked closed. > > I don't want it to be closed. Is it impossible to return "self" > in a non-closed class? > > *) > > class virtual run2 () as self = > inherit runaround () > method myself = (self :> runaround) > end;; Coercion operator ( e :> t ) is not always general enough. What it does is guess a type t' subtype of t independant of expression e, and then checks the type of expression e is an instance of type t'. For instance, if t = , then t' = . In this case, any subtype of t is an instance of type t'. But this is not always the case. Consider type t = as 'a. The types as 'b and are both subtypes of this type, but they are not instances of a common subtype of type t. So, one have to use a heuristic to find a type t' that works in most cases (I have changed the algorithm between ocaml 1.00 and ocaml 1.01, that's why your example compiles with the first version, but not with the second version). Let us come back to your example. You can see here the type t' guessed: #fun x -> (x :> runaround);; - : (< null : bool; next : 'a; myself : 'a; .. > as 'a) -> runaround = \_________________________________________________/ t' If you unify type t' with the type of self in class run2, you will get type runaround. Indeed, method myself of self has type runaround, so runaround = 'a (unification of types of myself) = type of self The type runaround is closed, hence the error message. The workaround is to use the more general coercion operator ( e : t' :> t ) when the other one fails. #class virtual run2 () as self = # inherit runaround () # method myself = (self : #runaround :> runaround) #end;; class virtual run2 (unit) = method myself : runaround virtual null : bool virtual next : runaround end Jerome