From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id MAA22284 for caml-redistribution; Wed, 29 May 1996 12:02:53 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.6.10/8.6.6) with ESMTP id DAA14284 for ; Wed, 29 May 1996 03:53:14 +0200 Received: from kurims.kurims.kyoto-u.ac.jp (kurims.kurims.kyoto-u.ac.jp [130.54.16.1]) by concorde.inria.fr (8.7.1/8.7.1) with ESMTP id DAA07350 for ; Wed, 29 May 1996 03:53:11 +0200 (MET DST) Received: from orion.kurims.kyoto-u.ac.jp (orion.kurims.kyoto-u.ac.jp [130.54.16.5]) by kurims.kurims.kyoto-u.ac.jp (8.7.3/3.4W2) with SMTP id KAA15885 for ; Wed, 29 May 1996 10:53:02 +0900 (JST) From: Jacques GARRIGUE Date: Wed, 29 May 1996 10:53:02 +0900 Message-Id: <199605290153.KAA16153@orion> To: caml-list@pauillac.inria.fr In-reply-to: <199605281843.LAA10975@wildtype.Stanford.EDU> (message from Andrew Conway on Tue, 28 May 1996 11:43:39 -0700 (PDT)) Subject: Re: Oo.copy Sender: weis >>>>> "Andrew" == Andrew Conway writes: >> From: Jacques GARRIGUE >> >>>>>>> ESPERET PHILIPPE <100060.2106@compuserve.com> writes: >> >> > I cannot understand how to access a fresh copy of an object with >> > O'Caml (Oo seems normally to copy only pointers). Thank you if someone >> > can explain me how to get such a copy (please see below for an example). >> >> > [ gives example of a class where a mutable element of the class >> > (an array) is not copied by OO.copy ] >> >> The problem is that your array is shared between the two copies. >> There are various specific ways to solve it. Andrew> I think that is a bad feature. I realise it may be unavoidable. Andrew> In particular, when I read the documentation for OO.copy, I assumed Andrew> that it was a function that descended the data structure, copying Andrew> all mutable structures. This seemed like a very useful thing to me Andrew> (and I wish it was available for any given type, not just classes). Andrew> I can immagine that this is impractical due to the overhead involved Andrew> in building specific "deep" copy functions for each data type defined Andrew> (that could possibly contain a mutable data structure), unless the Andrew> GC information contains enough of a specification to write a general Andrew> copy function similar to the general comparison functions. This would perhaps Andrew> only take one bit per block...saying whether the particular block Andrew> is mutable or not. On the other hand, I do realise that bits are expensive. It's not even clear what should be considered as mutable. For instance, strings are mutable, but most often you would expect deep copy to copy them. And what should you do about hashtables, etc... In fact, there is a way to build a general deep copy, if you don't care about how expensive it is: use the Obj module (about physical objects, not Oo), and read C headers. open Obj let deep_copy (x : 'a) : 'a = let copied = ref [] in let rec copy_obj x = if is_block x & (tag x < 249 or tag x = 252 or tag x = 254) then try List.assq x in:!copied with Not_found -> let x' = new_block (tag x) (size x) in for i = 0 to size x - 1 do set_field x' i (field x i) done; copied := (x,x') :: !copied; for i = 0 to size x' - 1 do let y = copy_obj (field x' i) in if y != field x' i then set_field x' i y done; x' else x in magic (copy_obj (repr x)) This is quite violent, but should work in most cases. Sharing is preserved. You can extend it to give a list of objects you want to leave shared with the original. >> One is to add an "unsharing" method in the virtual class, which is >> applied after copying. Andrew> Ugh! Didier gave a cleaner way to do it. I didn't read the formal definition for classes... Jacques --------------------------------------------------------------------------- Jacques Garrigue Kyoto University garrigue@kurims.kyoto-u.ac.jp JG