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 RAA07277 for caml-red; Wed, 31 Jan 2001 17:47:48 +0100 (MET) Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id RAA09464 for ; Wed, 31 Jan 2001 17:43:17 +0100 (MET) Received: from shell5.ba.best.com (shell5.ba.best.com [206.184.139.136]) by concorde.inria.fr (8.11.1/8.10.0) with ESMTP id f0VGhCX04744 for ; Wed, 31 Jan 2001 17:43:13 +0100 (MET) Received: from localhost (bpr@localhost) by shell5.ba.best.com (8.9.3/8.9.2/best.sh) with ESMTP id IAA14073; Wed, 31 Jan 2001 08:42:42 -0800 (PST) Date: Wed, 31 Jan 2001 08:42:41 -0800 (PST) From: Brian Rogoff To: Sylvain Kerjean cc: caml-list@inria.fr Subject: Re: classes mutually recursive In-Reply-To: <3A7542CB.6731EBDC@irisa.fr> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: weis@pauillac.inria.fr On Mon, 29 Jan 2001, Sylvain Kerjean wrote: > I have to program a class A whose method m produces an object of class > B,with the property that B inherits from A : > > class A = > ... > method m = new B > ... > end;; > > class B = > ... > inherit A > ... > end;; If both classes belong to the same module, simply connecting their definitions with an "and" will allow a mutually recursive class (and type!) definition. Here's a made-up example # class foo = object method make_bar = new bar method print = print_endline "foo" end and bar = object inherit foo method print = print_endline "bar" end;; class foo : object method make_bar : bar method print : unit end class bar : object method make_bar : bar method print : unit end # let f = new foo;; val f : foo = # let b = f#make_bar;; val b : bar = # f#print;; foo - : unit = () # b#print;; bar - : unit = () If you'd like the classes to reside in different modules, then the trick is to create interfaces or classes which break the mutual recursion, and inherit from those instead, since recursive modules are not yet supported by OCaml. Another made-up example. The following won't work module type DoctorType = sig class c : object method treat_patient : PatientType.c method bill_patient : PatientType.c end end ;; module type PatientType = sig class c : object method visit_doctor : DoctorType.c method pay_doctor : DoctorType.c end end ;; so we add a parent module which expresses an interface dependency and write the signatures in terms of that. module Forwards = sig class virtual patient_intf = object method virtual visit_doctor : doctor_intf method virtual pay_doctor : doctor_intf end and virtual doctor_intf = object method virtual treat_patient : patient_intf method virtual bill_patient : patient_intf end end ;; module type DoctorType = sig class c : object method treat_patient : Forwards.patient_intf method bill_patient : Forwards.patient_intf end end ;; module type PatientType = sig class c : object method visit_doctor : Forwards.doctor_intf method pay_doctor : Forwards.doctor_intf end end ;; > Of course it leads to a type clash, but as the manual exhibits an > example of the observer/notifier > problem, if someone could explain me a little more about a trick to get > the behaviour i need, it would be very kind !! I recommend that you read Didier Remy's excellent paper on this topic, which is on his web page. > PS : sorry for my poor english, and no i can not change my architecture > of classes cause i interface an existing API (for those who are > interested, it is the architecture of the BHandler/BLooper in BeOS) Hah, if my French were as good as your English, I wouldn't be apologizing. Fortunately this mailing list is helping ;-) -- Brian