From mboxrd@z Thu Jan 1 00:00:00 1970 X-Sympa-To: caml-list@inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p74GMb4A012333 for ; Thu, 4 Aug 2011 18:22:37 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtUAAE/GOk7D9eYikWdsb2JhbABDmFCPGBQBAQEBBw0LBxQFIIFCFAEXCwEFQD0WGAMCAQIBSw0IAQGHaqE6oCCGQgSYAgkVi0E X-IronPort-AV: E=Sophos;i="4.67,317,1309730400"; d="scan'208";a="104707578" Received: from mail1.bemta3.messagelabs.com ([195.245.230.34]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 04 Aug 2011 18:22:34 +0200 Received: from [85.158.138.147:48630] by server-4.bemta-3.messagelabs.com id D2/C5-31516-947CA3E4; Thu, 04 Aug 2011 16:22:33 +0000 X-VirusChecked: Checked X-Env-Sender: sebastien.furic@lmsintl.com X-Msg-Ref: server-6.tower-195.messagelabs.com!1312474956!44149077!1 X-StarScan-Version: 6.2.17; banners=-,-,- X-Originating-IP: [212.157.9.66] Received: (qmail 23575 invoked from network); 4 Aug 2011 16:22:36 -0000 Received: from unknown (HELO ROAP-EXHUB01.lmsintl.com) (212.157.9.66) by server-6.tower-195.messagelabs.com with RC4-SHA encrypted SMTP; 4 Aug 2011 16:22:36 -0000 Received: from [172.17.21.225] (172.17.21.225) by ROAP-EXHUB01.lmsintl.com (10.20.100.90) with Microsoft SMTP Server id 8.1.340.0; Thu, 4 Aug 2011 18:22:25 +0200 Message-ID: <4E3AC747.2010405@lmsintl.com> Date: Thu, 4 Aug 2011 18:22:31 +0200 From: =?windows-1252?Q?S=E9bastien_Furic?= User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20110624 Thunderbird/5.0 MIME-Version: 1.0 To: Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 8bit X-Validation-by: sebastien.furic@lmsintl.com Subject: [Caml-list] Questions about default instances Hello, What is the usual way in OCaml to define mutually recursive classes that share default instances? In order to illustrate my problem, let's suppose we would like to define a hierarchy of classes defining booleans /à la/ Smalltalk: -8<------------------------------------------------------------- class virtual object_ = object method virtual to_string: string end class virtual boolean = object inherit object_ method virtual not_: boolean method virtual or_: boolean Lazy.t -> boolean method virtual and_: boolean Lazy.t -> boolean method virtual if_: 'a . 'a Lazy.t -> 'a Lazy.t -> 'a end class false_class = object (self) inherit boolean method to_string = "false" method not_ = new true_class method or_ chk = Lazy.force chk method and_ _ = (self :> boolean) method if_ _ chk = Lazy.force chk end and true_class = object (self) inherit boolean method to_string = "true" method not_ = new false_class method or_ _ = (self :> boolean) method and_ chk = Lazy.force chk method if_ chk _ = Lazy.force chk end (* Default instances (that I would have preferred to inject directly in definitions above) *) let false_ = new false_class and true_ = new true_class -8<------------------------------------------------------------- Methods corresponding to message not_ in both false_class and true_class should ideally return a instance of, respectively, true_class and false_class that would have been created once and for all (instead of a fresh instance each time they are invoked). How does one achieve this in OCaml the functional way? (i.e., without resorting to references, but also, ideally, without resorting to lazy values) The use of immediate objects is IMO a better choice to implement booleans (because I don't want nor need to let users subclass false_class and true_class). Here is an attempt: -8<------------------------------------------------------------- (* Using the same definition of boolean above *) let rec false_ = object (self) inherit boolean method to_string = "false" method not_ = true_ method or_ chk = Lazy.force chk method and_ _ = self method if_ _ chk = Lazy.force chk end and true_ = object (self) inherit boolean method to_string = "true" method not_ = false_ method or_ _ = self method and_ chk = Lazy.force chk method if_ chk _ = Lazy.force chk end -8<------------------------------------------------------------- I get “Error: This kind of expression is not allowed as right-hand side of `let rec'”. I wonder why OCaml does not accept the definition of recursive values like above (notice that references to false_ and true_ are “protected” by method definitions). Wouldn't it be safe to extend recursive definitions with this pattern? Cheers, Sébastien.