From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p3TEaNox029925 for ; Fri, 29 Apr 2011 16:36:23 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvUCADvMuk1RZ90wkWdsb2JhbACEUaBPahQBAQEBCQsLBxQDIohxqkKREIEpg1SBAQSOaI4a X-IronPort-AV: E=Sophos;i="4.64,288,1301868000"; d="scan'208";a="98348917" Received: from mtaout02-winn.ispmail.ntl.com ([81.103.221.48]) by mail2-smtp-roc.national.inria.fr with ESMTP; 29 Apr 2011 16:36:18 +0200 Received: from aamtaout03-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout02-winn.ispmail.ntl.com (InterMail vM.7.08.04.00 201-2186-134-20080326) with ESMTP id <20110429143617.HARX6199.mtaout02-winn.ispmail.ntl.com@aamtaout03-winn.ispmail.ntl.com>; Fri, 29 Apr 2011 15:36:17 +0100 Received: from romulus.metastack.com ([81.102.132.77]) by aamtaout03-winn.ispmail.ntl.com (InterMail vG.3.00.04.00 201-2196-133-20080908) with ESMTP id <20110429143617.SFBO24017.aamtaout03-winn.ispmail.ntl.com@romulus.metastack.com>; Fri, 29 Apr 2011 15:36:17 +0100 Received: from remus.metastack.local ([172.16.0.1]) by romulus.metastack.com (8.14.2/8.14.2) with ESMTP id p3TEaDKV023109 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=FAIL); Fri, 29 Apr 2011 15:36:14 +0100 Received: from Remus.metastack.local ([fe80::547c:3c42:e1da:eda2]) by Remus.metastack.local ([fe80::547c:3c42:e1da:eda2%11]) with mapi; Fri, 29 Apr 2011 15:36:13 +0100 From: David Allsopp To: "louis.jachiet@ens.fr" , "caml-list@inria.fr" Thread-Topic: [Caml-list] Differences between Array and Strings Thread-Index: AQHMBmPYMy4Cde7a8ESwOoNziK5/G5R04qZw Date: Fri, 29 Apr 2011 14:36:11 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Organization: MetaStack Solutions Ltd. X-Scanned-By: MIMEDefang 2.65 on 81.102.132.77 X-Cloudmark-Analysis: v=1.1 cv=R50lirqlHffDPPkwUlkuVa99MrvKdVWo//yz83qex8g= c=1 sm=0 a=gmb3etpw-7oA:10 a=cTs9vV391PwA:10 a=IkcTkHD0fZMA:10 a=xqWC_Br6kY4A:10 a=zIoFKh15WheM3cP3X10A:9 a=krYQ4U5ZFI6sBONTRC4A:7 a=QEXdDO2ut3YA:10 a=HpAAvcLHHh0Zw7uRqdWCyQ==:117 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by walapai.inria.fr id p3TEaNox029925 Subject: RE: [Caml-list] Differences between Array and Strings Louis Jachiet wrote: > Hi, I'am failing to understand the behavior of the code below. Why the > string is not regenerated ? Why strings and array have not the same > behavior ? This has been commented on before (see the list archives) - if I understand correctly, it's a consequence of the code generator... > > let l () = "1" ;; Compiles to (let (l/1030 (function param/1032 "1")) (makeblock 0 l/1030)) i.e. a reference to a constant with value "1" - not an allocation. So l always returns the same physical string, rather than allocating a new one. This makes sense if you're assuming that strings are by default used immutably (there have been plenty of discussions in the past on the relative merits of having the same string type for both immutable and mutable strings) However, the constants clearly aren't used in a pool: # let f () = "1";; val f : unit -> string = # let g () = "1";; val g : unit -> string = given: # f () == g ();; - : bool = false > > (l ()).[0] <- '2';; > > l ();; > > l()==l();; > > > let l () = [|1|] ;; > > (l ()).(0) <- 2;; This, however, compiles to (let (l/1030 (function param/1032 (makearray 1))) (makeblock 0 l/1030)) i.e. it allocates a fresh array each time. The behaviour of the compiler would suggest that its authors considered string "constants" to be just that but the syntax for array literals to be simply sugar for an array allocation followed by initialisation of the members. As a rule of thumb, if you're dealing with mutable strings, it's a good idea to be very clear who allocated them and where so personally I quite like the fact that the compiler forces you to need to write: let l () = String.copy "1" which will behave as you expected. HTH, David