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 PAA03590; Mon, 29 Jul 2002 15:59:54 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f 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 PAA03524 for ; Mon, 29 Jul 2002 15:59:53 +0200 (MET DST) Received: from brouilly.inria.fr (brouilly.inria.fr [128.93.8.4]) by concorde.inria.fr (8.11.1/8.11.1) with ESMTP id g6TDmXH22933; Mon, 29 Jul 2002 15:48:34 +0200 (MET DST) Received: by brouilly.inria.fr (Postfix, from userid 11404) id 91CE44947; Mon, 29 Jul 2002 15:48:33 +0200 (CEST) To: Oleg , caml-list@inria.fr Subject: Re: [Caml-list] marshalling and code changes References: <200207291249.IAA02832@dewberry.cc.columbia.edu> Reply-To: James Leifer From: James Leifer Date: Mon, 29 Jul 2002 15:48:33 +0200 In-Reply-To: <200207291249.IAA02832@dewberry.cc.columbia.edu> (Oleg's message of "Mon, 29 Jul 2002 08:50:26 -0400") Message-ID: User-Agent: Gnus/5.090006 (Oort Gnus v0.06) Emacs/20.7 (i386-mandrake-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk Greetings Oleg, The problem you raise is one that I (and others here: Gilles.Peskine@inria.fr, Jun.Furuse@inria.fr, and Pierre.Weis@inria) have been thinking about. > Suppose I use Marshall module (and input_value / output_value pervasives) to > serialize a sophisticated data type. If I make [small] changes to this data > type, what is the best way to convert old saved data? Currently if you want to be safe, you need to read the data back under precisely the same type used to write it. You can then do the conversion by writing the appropriate Ocaml function. > What if the new type is a supertype to the old one, can I load it safely? Nothing is guaranteed, currently. > I tried it with > > type old_type = Float of float | Int of int ;; > type new_type = Float of float | Int of int | S of string;; > > and it seemed to have worked with input_value and output_value. Input_value and output_value are not safe (as stated in the manual): the fact that this worked is a ``fluke'' due to the way values of unions are represented. If you go in the other direction (saving S "hello" and reloading it as old_type), you'll get a crash, as illustrated by the following example: Open two terminal windows each running an ocaml top-level. In the first type: type new_type = Float of float | Int of int | S of string;; let fd = open_out "/tmp/testfile" in output_value fd (S "hello"); close_out fd;; Then in the second type: type old_type = Float of float | Int of int;; let fd = open_in "/tmp/testfile" in match input_value fd with Float _ -> "float" | Int _ -> "int";; As a practical programming discipline, put all types you want to use for input/output in a single module and coerce every read and write explicitly to the types defined in that module. If you do this systematically, you will be able to detect any type errors at compile-time. Another route is to use the many XML writers and parsers that have been circulating the list recently. These are unlikely to give you the same performance though. I'm working (with the above-mentioned colleagues) on run-time checking for marshalling. This gets hairy though if one wants to deal with abstract types... Warmest wishes, James Leifer INRIA Rocquencourt ------------------- 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