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 IAA22397 for caml-redistribution; Fri, 12 Mar 1999 08:49:55 +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 FAA18253 for ; Fri, 12 Mar 1999 05:20:48 +0100 (MET) Received: from macadam.mpce.mq.edu.au (macadam.mpce.mq.edu.au [137.111.216.12]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id FAA12747 for ; Fri, 12 Mar 1999 05:20:44 +0100 (MET) Received: from krakatoa.mpce.mq.edu.au (clad@krakatoa.mpce.mq.edu.au [137.111.240.12]) by macadam.mpce.mq.edu.au (8.8.8/8.8.8) with ESMTP id PAA13104; Fri, 12 Mar 1999 15:20:26 +1100 (EST) Received: from localhost (clad@localhost) by krakatoa.mpce.mq.edu.au (8.9.1a/8.9.1) with ESMTP id PAA22210; Fri, 12 Mar 1999 15:20:24 +1100 (EST) Date: Fri, 12 Mar 1999 15:20:24 +1100 (EST) From: David Clarke To: caml-list@inria.fr cc: williamc@dai.ed.ac.uk Subject: Anonymous object/class (revisited) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: weis Hi, The following camlp4 preprocessor code allows you to use anonymous objects in ocaml, including objects inside classes and other anonymous objects. It is a slight improvement on William Chester's implementation from less than a month ago. It also contains a little more documentation and an example. The code transforms an anonymous object declaration into a class defined within a local module, and then creates an instance of that class. Simple. The code follows (with an example in the comment). If you find this useful, implement any extensions, find some problems or limitations, etc etc, I would love to know. Dave ---------------======------------=====000000------0===-=0===-0==------0-- David Clarke "Well, you'll work harder with a gun in your back http://www.mri.mq.edu.au/~clad for a bowl of rice a day" ---------------======------------=====000000------0===-=0===-0==------0-- ----------- proto.ml -------------- (* CAMLP4 code extending OCAML with anonymous objects. An anonymous object can appear anywhere an expression can, including inside classes and other anonymous objects. An example is object val mutable data = 10 method update x = data <- x method get = data end which is translated to let module Mod1 = struct class cla2 = object val mutable data = 10 method update x = data <- x method get = data end end in new Mod1.cla2 The syntax of anonymous objects is the same as the object ... end clause of the class-expr clause in the grammar. Limitations: There are bound to be some. *) let genname = let count = ref 0 in function pre -> count := !count + 1; pre ^ string_of_int(!count);; open Pcaml;; EXTEND expr: LAST [[ ce = class_expr -> let modname = genname "Mod" in let cname = genname "cla" in let longname = [modname; cname] in <:expr< let module $modname$ = struct class $cname$ = $ce$; end in new $list:longname$ >> ]]; END;; -------- instructions ----------- Needs camlp4. To compile: ocamlc -pp "camlp4o pa_extend.cmo q_MLast.cmo" -I `camlp4 -where` -c proto.ml To run just preprocessor: camlp4o pr_o.cmo ./proto.cmo test.ml To apply to your own programs: ocamlc -pp "camlp4o ./proto.cmo" -o tester test.ml --------- test.ml -------------- (* this is a test file for the anonymous objects extension to OCAML *) (* a simple example *) let z = object val mutable data = 10 method update x = data <- x method get = data end;; let y = z#get;; let _ = print_int y; print_newline (); flush stdout;; (* an example with an lexically scoped inner object *) let outer = object (oself) val mutable data = "hello" method print = print_string data; print_newline () method update x = data <- x method extern = object method update x = data <- x method downdate x = oself#update x end end;; let _ = outer#print;; let _ = outer#update "spam"; outer#print;; let ex = outer#extern;; let _ = ex#update "jimmy jo"; outer#print;; let _ = ex#downdate "flavour of the month"; outer#print; flush stdout;; ------- EOF ----------