From mboxrd@z Thu Jan 1 00:00:00 1970 X-Sympa-To: caml-list@inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q2UF0F3u014925 for ; Fri, 30 Mar 2012 17:00:15 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqkDAOLJdU+K54gDgWdsb2JhbAArEQm4ayIBARYmJ4IJAQEEAScLAQVAEQsYCRYPCQMCAQIBRRMGAgKIAAULKbpBineGGQSIWo4ahF+NQw X-IronPort-AV: E=Sophos;i="4.75,344,1330902000"; d="scan'208";a="151972881" Received: from rouge.crans.org ([138.231.136.3]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 30 Mar 2012 17:00:10 +0200 Received: from localhost (localhost.crans.org [127.0.0.1]) by rouge.crans.org (Postfix) with ESMTP id 470658075 for ; Fri, 30 Mar 2012 17:00:10 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at crans.org Received: from rouge.crans.org ([10.231.136.3]) by localhost (rouge.crans.org [10.231.136.3]) (amavisd-new, port 10024) with LMTP id cHqvHL-806wm for ; Fri, 30 Mar 2012 17:00:10 +0200 (CEST) Received: from [128.255.45.252] (dpmlh003.divms.uiowa.edu [128.255.45.252]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by rouge.crans.org (Postfix) with ESMTPSA id DD1B1806D for ; Fri, 30 Mar 2012 17:00:09 +0200 (CEST) Message-ID: <4F75CA78.4080103@lri.fr> Date: Fri, 30 Mar 2012 10:00:08 -0500 From: =?ISO-8859-1?Q?Fran=E7ois_Bobot?= User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111114 Icedove/3.1.16 MIME-Version: 1.0 To: caml-list@inria.fr References: <87fwcx6ejm.fsf@frosties.localnet> <4F74E647.1040603@lri.fr> <87k4229td1.fsf@frosties.localnet> In-Reply-To: <87k4229td1.fsf@frosties.localnet> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit X-Validation-by: bobot@lri.fr Subject: Re: [Caml-list] Wish: mutable variant types, equivalence with records On 30/03/2012 07:16, Goswin von Brederlow wrote: > François Bobot writes: > >> On 24/03/2012 13:45, Wojciech Meyer wrote: >>> Please see [1], Alain Frisch has been working recently on implementing >>> in-line records for constructor arguments. >>> >>> It's more implementation/design implications than people might think. >>> >>> [1] http://caml.inria.fr/mantis/view.php?id=5528 >> >> In the thread of this proposed feature, there is a remark that inlined >> record and normal record can become competing features. There is also >> the burden that inlined record as proposed can be modified only in >> pattern matching. >> >> But can't we consider that, for a semantic, syntax and typing perspective: >> >> type t = >> | A of string >> | B of ({msg: string; mutable foo:int} as t2) >> | C >> >> is exactly the same thing than: >> >> type t = >> | A of string >> | B of t2 >> | C >> >> and t2 = {msg: string; mutable foo:int} > > That would change existing code because B of t2 currently is a Block of > size 1 with tag B and pointer to a record of type t2. I don't propose to change how is compiled the second definition. Just that if a developer use the first definition in a module he can consider that he define t and t2 like in the second definition. The only exception is if you use Obj.magic: Obj.magic (B r) == Obj.magic r. But Obj.magic is not in the semantic I assume. > >> The only difference is that when you create a record of type t2 the >> tag is directly the one of B in the first case and is the default tag >> for record (the first tag if I remember well) in the second case. So >> in the first case applying the constructor B is just the identity. > > Maybe the type of a record could be altered to, at least internally, > include a tag value: Every records already include a tag value, it's just always the same: the tag of the first non-constant constructor of a sum type. > > type t = A of string | B of ({msg: string; mutable foo:int} as t2) | C > type t2 = {[B] x : int; } > > The inline record would be identical to the external record with tag > value and (t2 :> t) would work even implicitly. I'm not sure that we should make implicit conversion (inference? principality?). But that B r is a noop can be very interesting. If we want to play to extend this feature (perhaps too much) we can play with conversion between sum type without cost by allowing Ap to be also the identity: type tpublic = | A of ({... } as ta) | B of ({... } as tb) type tprivate = | Ap of ta | Bp of tb | Cp of ... Since A,ta and Ap share the same tag the following function is the identity: let private_of_public = function | A x -> Ap x | B x -> Bp x and this one just make one test: let public_of_private = function | Ap x -> A x | Bp x -> B x | Cp _ -> invalid_arg "public_of_private: non-public value" And the semantic is the same than if I define the type ta and tb as usual record, just the compilation change. -- François Bobot