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 OAA26665 for caml-redistribution; Wed, 20 Jan 1999 14:03:51 +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 MAA24015 for ; Wed, 20 Jan 1999 12:49:59 +0100 (MET) Received: from irritatie.cs.kun.nl (irritatie.cs.kun.nl [131.174.33.129]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id MAA00530 for ; Wed, 20 Jan 1999 12:49:57 +0100 (MET) Received: (from tews@localhost) by irritatie.cs.kun.nl (8.8.7/8.8.7) id MAA09911; Wed, 20 Jan 1999 12:50:21 +0100 Date: Wed, 20 Jan 1999 12:50:21 +0100 Message-Id: <199901201150.MAA09911@irritatie.cs.kun.nl> From: Hendrik Tews MIME-Version: 1.0 Content-Transfer-Encoding: 7bit To: caml-list@inria.fr Subject: Re: subtyping and inheritance In-Reply-To: <199901182118.WAA09639@miss.wu-wien.ac.at> References: <19990118205542.06048@pauillac.inria.fr> <199901182118.WAA09639@miss.wu-wien.ac.at> X-Mailer: VM 6.22 under 19.15 XEmacs Lucid Sender: weis Hi, Markus Mottl writes (in reply to Jerome Vouillon): From: Markus Mottl Date: Mon, 18 Jan 1999 22:18:40 +0100 (MET) Subject: Re: subtyping and inheritance Hello, > So, you want to be able to select a method depending on two > objets. [...] To solve this problem I've done something similar (defined an extra comparison method for symbols in class symbol) - I don't know of any better means. But as is obvious: this workaround unfortunately does not really exhibit the virtues of code reuse... This is true. But what you really need to solve your problem is a feature called sometimes "(covariant) specialization of code". Ocaml does not have this feature. Therefore you can not hope for a solution which is typesafe and supports code reuse. Ocaml does provide the feature "contravariant subtyping", which gives you a save subtype relation. There is nice paper of Guiseppe Castagna "Covariance and Contravariance: Conflict without a Cause" [1] which discusses those features and their relation. This paper and the references therein contain also proposals how to integrate specialization of code into a record based object oriented language. Is their any hope, that ocaml adopts this (or any other) solution in the future, such that Markus can implement comparison of terminals and symbols in a clean way? There was already a proposal how to solve the problem by Jerome Vouillon. Just for demonstration I append another solution, which uses a self implemented type case. It supports code reuse better, but loses type security by using the Obj module. Maybe one of the people who "understand the whole source code for the O'Caml compiler, runtime and libraries" and by that can use the Obj module, can comment on its use here. ;-) [1] G. Castagna. Covariance and contravariance: conflict without a cause. ACM Transactions on Programming Languages and Systems 17(3):431-447, March 1995. Also available at http://www.ens.fr/~castagna/pub.html. Gruss, Hendrik exception No_subclass (* always use unique numbers for this_dynamic_type for every class, such that this_dynamic_type(class1) mod this_dynamic_type(class2) = 0 if and only if class1 inherits from class2 *) class top = let this_dynamic_type = 1 in object (self : 'self) method dynamic_type = this_dynamic_type method subclass (super : int) (sub : top) = (* sub belongs to a subclass of super *) sub#dynamic_type mod super = 0 method eq (x : top) = print_string "top = top ? "; true end class left (l1 : int) = let this_dynamic_type = 2 in object (self : 'self) inherit top as super method dynamic_type = this_dynamic_type method private cast_left other = if self#subclass this_dynamic_type other then (Obj.magic(other) : left) else raise No_subclass method eq (x : top) = try let x' = self#cast_left(x) in begin print_string "left = left ? "; self#m_left = x'#m_left end with No_subclass -> super#eq(x) method m_left = l1 end class right (r1 : int) = let this_dynamic_type = 3 in object (self : 'self) inherit top as super method dynamic_type = this_dynamic_type method private cast_right other = if self#subclass this_dynamic_type other then (Obj.magic(other) : right) else raise No_subclass method eq (x : top) = try let x' = self#cast_right(x) in begin print_string "right = right ? "; self#m_right = x'#m_right end with No_subclass -> super#eq(x) method m_right = r1 end let l1 = new left 1 let l2 = new left 2 let r1 = new right 1 let x = l1#eq(l2:>top) let y = r1#eq(l1:>top)