From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id BAA01202; Fri, 27 Feb 2004 01:46:04 +0100 (MET) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f 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 BAA01526 for ; Fri, 27 Feb 2004 01:46:03 +0100 (MET) Received: from swordfish.cs.caltech.edu (swordfish.cs.caltech.edu [131.215.44.124]) by nez-perce.inria.fr (8.12.10/8.12.10) with ESMTP id i1R0k5Iq007305 for ; Fri, 27 Feb 2004 01:46:06 +0100 Received: from orchestra.cs.caltech.edu (orchestra.cs.caltech.edu [131.215.44.20]) by swordfish.cs.caltech.edu (Postfix) with ESMTP id D79AFDF271 for ; Thu, 26 Feb 2004 16:46:00 -0800 (PST) Received: by orchestra.cs.caltech.edu (Postfix, from userid 2554) id C85CE9BBA2; Thu, 26 Feb 2004 16:45:57 -0800 (PST) From: Michael Vanier To: caml-list@inria.fr Subject: [Caml-list] extensible records? Message-Id: <20040227004557.C85CE9BBA2@orchestra.cs.caltech.edu> Date: Thu, 26 Feb 2004 16:45:57 -0800 (PST) X-Miltered: at nez-perce by Joe's j-chkmail ("http://j-chkmail.ensmp.fr")! X-Loop: caml-list@inria.fr X-Spam: no; 0.00; vanier:01 mvanier:01 extensible:01 figuring:01 floats:01 python:01 mli:01 mli:01 extensible:01 infer:01 compiler:01 ints:01 ocaml:01 ocaml:01 variants:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk Hi everyone! I'm having a problem figuring out how to implement something in ocaml, and I'd like to solicit advice. I'm writing a little dynamically-typed language in ocaml, and I want to be able to add new types to the language without having to add new primitive types to the system. So, for instance, my basic type definition looks something like this: type data = Int of int | Float of float | ... Now let's say I want to add a type for files. I don't want this to be a type at the same level as ints or floats, because I want users to be able to add their own types to the language without hacking the core type definition (which is possible in, for instance, python). So my ideal solution would be something like this (not real ocaml code): (* types.mli *) type data = Int of int | Float of float | ... | Extension of extension type extension = [] (* nothing yet, not valid ocaml *) (* files.mli *) extension File of out_channel (* not valid ocaml *) (* files.ml *) let close (d : data) = match data with Extension ext -> (match ext with File f -> (* close the file *) | _ -> raise (Failure "invalid type")) | _ -> raise (Failure "invalid type") I can see two ways I can do this already, but both involve abusing the exception system. Way 1: (* types.mli *) type data = Int of int | Float of float | ... | Extension of unit -> unit (* files.ml *) exception File of out_channel let open_file filename = (* open the file as new_file *) raise (File new_file) let close (d : data) = match data with Extension ext -> try ext () with ext' -> (match ext' with File f -> (* close the file *) | _ -> raise (Failure "invalid type")) | _ -> raise (Failure "invalid type") Aside from abusing the exception system, I've been told that this would be slow due to the exception handling overhead. A more direct way would be: (* types.mli *) type data = Int of int | Float of float | ... | Extension of exn (* files.ml *) exception File of out_channel let close (d : data) = match data with Extension ext -> (match ext with File f -> (* close the file *) | _ -> raise (Failure "invalid type"))) | _ -> raise (Failure "invalid type") This would (I think) work, and wouldn't involve excessive overhead. But really, all I'm doing is abusing the fact that exceptions are the one kind of extensible record type built in to ocaml. What I want to know is: is there a better way to do this? I thought of using polymorphic variant types, but my (limited) understanding is that you either declare all possible variants straight up in the .mli file (which totally defeats my purpose) or you don't declare anything and let the compiler infer the type (which I don't know how to write into a .mli file). If this can be done with polymorphic variants, how would I do it? Alternatively, if this can be done with objects, how would I do it? Or should I just stick with abusing exceptions? Cheers, Mike ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners