From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p9F85Ev3005266 for ; Sat, 15 Oct 2011 10:05:14 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AiABAAg+mU5CbwQdkWdsb2JhbABDqGUiAQEBAQkLCwcUBCGCNTgCOxYYAwIBAgFLDQgBAawRkjIHiASIBpEhjE0 X-IronPort-AV: E=Sophos;i="4.69,350,1315173600"; d="scan'208";a="113003087" Received: from out5.smtp.messagingengine.com ([66.111.4.29]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 15 Oct 2011 10:05:09 +0200 Received: from compute5.internal (compute5.nyi.mail.srv.osa [10.202.2.45]) by gateway1.nyi.mail.srv.osa (Postfix) with ESMTP id BB9B420754 for ; Sat, 15 Oct 2011 04:05:07 -0400 (EDT) Received: from frontend1.nyi.mail.srv.osa ([10.202.2.160]) by compute5.internal (MEProxy); Sat, 15 Oct 2011 04:05:07 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=message-id:date:from:mime-version:to :subject:content-type:content-transfer-encoding; s=smtpout; bh=H dExG0RNb2T0iL7pXSMZWyCMpPM=; b=UrFfHvRSELtMXohZYdeSI1PyyH3I1WdEz ob/gXqm2wJ3kln2bUuLQhuIOYBowBZo4vRp/Fq34aS+rZUD2KRoOMUyaUzbEWa+h oVqzyhexi9dg2cwTspMnPdGwfjiL4b6u078WLxTifBhvn7utbL/MevjiB87g5ccQ JwC1gBtpyg= X-Sasl-enc: 3wy2FtgyTO5094LsDjD7o2KzHn5L/ku/X1kT0+I9mB+k 1318665907 Received: from [192.168.2.2] (c-98-248-39-171.hsd1.ca.comcast.net [98.248.39.171]) by mail.messagingengine.com (Postfix) with ESMTPSA id 5827A4050CC for ; Sat, 15 Oct 2011 04:05:07 -0400 (EDT) Message-ID: <4E993FE5.7080409@ens-lyon.org> Date: Sat, 15 Oct 2011 01:10:13 -0700 From: Martin Jambon User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20101023 Lightning/1.0b3pre Thunderbird/3.1.3 MIME-Version: 1.0 To: OCaml Mailing List Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: [Caml-list] How to mutate immutable record fields? Dear fellow OCamlers, Hints on how to solve this, using any means necessary, will be greatly appreciated. Purpose: deserializing a record efficiently, i.e. creating a record whose field values are available one after another in an unpredictable order. Problem: Obj.set_field does the job in most cases but not in the example below. How to make it work? (we don't want to use pure OCaml option refs to store field values before putting them into the record because that's too slow) Requirements: - performance is critical - code will be machine-generated - immutable record fields must be supported The example below shows a record type for which a straight Obj.set_field produces a field that cannot be read correctly with the usual dot notation (ocamlopt only, tested on Linux/amd64 with OCaml 3.12.1 and 3.11.2). $ ocamlopt -o foo.opt foo.ml; ./foo.opt ERROR t.foo is None OK field0 $ cat foo.ml (* ocamlopt -o foo.opt foo.ml; ./foo.opt *) type t = { foo : int option; bar : int; } let create () = { { foo = None; bar = 42 } with foo = None } let () = assert (create () != create ()); let t = create () in let f = Some 17 in Obj.set_field (Obj.repr t) 0 (Obj.repr f); let f1 = t.foo in let f2 = Obj.obj (Obj.field (Obj.repr t) 0) in if f1 = f then print_endline "OK t.foo" else if f1 = None then print_endline "ERROR t.foo is None" else print_endline "ERROR t.foo is something strange"; if f2 = f then print_endline "OK field0" else if f2 = None then print_endline "ERROR field0 is None" else print_endline "ERROR field0 is something strange"