From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 455D6BC57 for ; Tue, 8 Jun 2010 11:14:14 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmkCAD6mDUxRZ90vkWdsb2JhbACeQRUBAQEBCQsKBxEDH70PgliCPgQ X-IronPort-AV: E=Sophos;i="4.53,383,1272837600"; d="scan'208";a="51957991" Received: from mtaout01-winn.ispmail.ntl.com ([81.103.221.47]) by mail3-smtp-sop.national.inria.fr with ESMTP; 08 Jun 2010 11:14:13 +0200 Received: from aamtaout02-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout01-winn.ispmail.ntl.com (InterMail vM.7.08.04.00 201-2186-134-20080326) with ESMTP id <20100608091409.XKJV3266.mtaout01-winn.ispmail.ntl.com@aamtaout02-winn.ispmail.ntl.com>; Tue, 8 Jun 2010 10:14:09 +0100 Received: from romulus.metastack.com ([81.102.132.77]) by aamtaout02-winn.ispmail.ntl.com (InterMail vG.2.02.00.01 201-2161-120-102-20060912) with ESMTP id <20100608091409.SURZ1586.aamtaout02-winn.ispmail.ntl.com@romulus.metastack.com>; Tue, 8 Jun 2010 10:14:09 +0100 Received: from Tenor ([172.16.0.8]) (authenticated bits=0) by romulus.metastack.com (8.14.2/8.14.2) with ESMTP id o589E2nR009097 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Tue, 8 Jun 2010 10:14:03 +0100 From: "David Allsopp" To: "'bluestorm'" Cc: "'W Dan Meyer'" , References: <4C0D3557.1020200@gmail.com> <010d01cb0672$09f3eb90$1ddbc2b0$@romulus.metastack.com> <4C0D4C88.4070102@gmail.com> <877hma78xf.fsf@gmail.com> <013a01cb06de$32c6d930$98548b90$@romulus.metastack.com> In-Reply-To: Subject: RE: [Caml-list] Converting variants with only constant constructors to integers Date: Tue, 8 Jun 2010 10:14:02 +0100 Message-ID: <015201cb06ea$f06adc00$d1409400$@romulus.metastack.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQK3OCAoaAveGworypJxQY6jcfYL4QG5R1OKAl4LCCQB8HFXWwG5f4A0AZ1ERFMCOcHmgwHorL8M Content-Language: en-gb Organization: MetaStack Solutions Ltd. X-Scanned-By: MIMEDefang 2.65 on 81.102.132.77 X-Cloudmark-Analysis: v=1.1 cv=ZtHxNT4mZm3rCuM0SmWmgWxeBwJsziC8EqOrwwVkrhA= c=1 sm=0 a=mlUxVNNIk8MA:10 a=VZGMvYHv9TIA:10 a=8sW17jYxVu0A:10 a=8nJEP1OIZ-IA:10 a=65itoQf_3es1mNEEn0kA:9 a=RFDrroZEF-oDJ5ZLup3drwt0lc4A:4 a=wPNLvfGTeEIA:10 a=HpAAvcLHHh0Zw7uRqdWCyQ==:117 X-Spam: no; 0.00; variants:01 constructors:01 integers:01 constructors:01 restrictive:01 ocaml:01 compiler:01 hashtable:01 compiler:01 camlp:01 wrote:01 integer:01 caml-list:01 int:01 int:01 Gabriel Scherer wrote: > Incidentally, the general function for getting a unique integer for a > variant type with non-constant constructors isn't that bad either: > > let int_of_gen x =3D >=A0let x =3D Obj.repr x >=A0in >=A0 =A0if Obj.is_block x >=A0 =A0then -1 * Obj.tag x - 1 >=A0 =A0else (Obj.magic x : int) > > I consider that version much better. You could also write it in a more restrictive way : > >=A0let to_int x =3D >=A0=A0 let repr =3D Obj.repr x in >=A0=A0 if Obj.is_int repr >=A0=A0 then (Obj.obj repr : int) >=A0=A0 else invalid_arg "to_int";; (that doesn't quite do the same thing but I don't think that was your = point) My "problem" is that for each specific case where it's only constant constructors, I can't help but feel guilty that code will execute for = the conversion of a value to the same value (%identity is a no-op most of = the time). It's not that everything has to be pointlessly micro-optimised, = but you know what I mean? > The good point about those is that they check that the memory representation is compatible=20 > before casting (while=A0the "%identity" does not). They're safer. Of = course, they still break=20 > parametricity if used polymorphically, so as you said type should be constrained. > I still would prefer the more direct pattern-matching definition : it = may require code=20 > generation not to be tedious, but the generated code is an honourable OCaml citizen. Of course, if you have the following: type t =3D A | B | C let int_of_t =3D function A -> 0 | B -> 1 | C -> 2 Then in fact I believe that the compiler already converts that to a hashtable lookup instead of a sequence of jumps so it would be fairly reasonable (and easy) to have the compiler spot that the match is = exactly a conversion to the tag value and so remove the match completely (and = given that the compiler already has two different strategies for match = clauses, it's not even that inconsistent). camlp4 of course solves the generation problem (but there's no need to tell you that!!) David