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 mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 18F39BC57 for ; Mon, 1 Mar 2010 13:53:03 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkQCAHtHi0tRZ906mWdsb2JhbACDBZgJFQEBAQEBCAsKBxMiqgSPMoE0gRuBQmoEgzM X-IronPort-AV: E=Sophos;i="4.49,560,1262559600"; d="scan'208";a="57964635" Received: from queueout04-winn.ispmail.ntl.com ([81.103.221.58]) by mail4-smtp-sop.national.inria.fr with ESMTP; 01 Mar 2010 13:53:02 +0100 Received: from aamtaout01-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 <20100301124958.GAOZ4474.mtaout02-winn.ispmail.ntl.com@aamtaout01-winn.ispmail.ntl.com>; Mon, 1 Mar 2010 12:49:58 +0000 Received: from romulus.metastack.com ([81.102.132.77]) by aamtaout01-winn.ispmail.ntl.com (InterMail vG.2.02.00.01 201-2161-120-102-20060912) with ESMTP id <20100301124958.HPKI13254.aamtaout01-winn.ispmail.ntl.com@romulus.metastack.com>; Mon, 1 Mar 2010 12:49:58 +0000 Received: from Tenor ([212.183.140.34]) (authenticated bits=0) by romulus.metastack.com (8.14.2/8.14.2) with ESMTP id o21CnlGh017589 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Mon, 1 Mar 2010 12:49:54 GMT From: "David Allsopp" To: , "=?UTF-8?Q?'St=C3=A9phane_Glondu'?=" Cc: "'OCaml List'" References: <4B887AED.3090005@citycable.ch> <4B88F32C.3050701@citycable.ch> <87k4tyoq3m.fsf@frosties.localdomain> <4B891A0C.604@citycable.ch> <76EDF2F2-8B02-4C97-B083-EC74630D8ECA@mpi-sws.org> <4B896026.2070805@citycable.ch> <4B89780E.5080305@citycable.ch> <4B898179.1000600@citycable.ch> <4B8B9D15.7070300@glondu.net> <4B8BA350.8090404@citycable.ch> In-Reply-To: <4B8BA350.8090404@citycable.ch> Subject: RE: [Caml-list] Recursive subtyping issue Date: Mon, 1 Mar 2010 12:49:53 -0000 Message-ID: <000d01cab93d$b095c770$11c15650$@romulus.metastack.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQG++dev6usjy+MhCCiCMQMXQZ/itALZ1N3bAhDBEaACMQ+SQQJi1d9iAtZavDECFUz3DwKgUGxPA1Sa9KMBLUbUWwG7IK8HAbcyleE= 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=wNs1GRMElQMA:10 a=SdAVNbPx-4GtQR0nfDUA:9 a=U4x5iqHAspsAR8zNRCzk5vf8VCUA:4 a=HpAAvcLHHh0Zw7uRqdWCyQ==:117 X-Spam: no; 0.00; recursive:01 subtyping:01 guillaume:01 guillaume:01 untyped:01 untyped:01 val:01 val:01 subtyping:01 foo:01 foo:01 mli:01 ocamlopt:01 runtime:01 runtime:01 Guillaume Yziquel wrote: > St=C3=A9phane Glondu a =C3=A9crit : > > Guillaume Yziquel a =C3=A9crit : > >>> # type untyped;; > >>> type untyped > >>> # type 'a typed =3D private untyped;; > >>> type 'a typed =3D private untyped > >>> # type -'typing tau =3D private obj > >>> and 'a t =3D 'a typed tau > >>> and obj =3D private untyped tau;; > >>> type 'a tau =3D private obj > >>> and 'a t =3D 'a typed tau > >>> and obj =3D private untyped tau > >>> # let f : 'a t -> obj =3D fun x -> (x : 'a t :> obj);; val f : 'a = t -> > >>> obj =3D # let g : obj -> 'a t =3D fun x -> (x : obj :> 'a = t);; val > >>> g : obj -> 'a t =3D # > > > > Why don't you just declare 'a t to be synonym for obj in the > > implementation of your module, declare them as abstract in its > > interface, and export the specially typed identities f and g? >=20 > Because subtyping seems more efficient than applying a noop function. I wholeheartedly agree that doing this in the type system is much = cleaner than using noop/coercion functions but I don't think that = there's any difference in terms of efficiency. If the noop/coercion = functions are correctly coded then they will be of the form: external foo_of_bar : bar -> foo =3D "%identity" in *both* the .ml and .mli file for the module in question. I'm = virtually certain that ocamlopt eliminates calls to the %identity = primitive. > And this code might run really often, so I do not like very much the > idea of having noop functions running really often. See previous; I don't think it makes a difference (to runtime = performance, anyway). > Moreover, having conversion functions is not really handy, from a > syntactic point of view: It's quite convenient to write something like >=20 > let f : string -> obj :> string -> float t =3D blah blah blah... >=20 > than doing the explicit, runtime, casting in the definition of f. Agreed - this is where your approach is really neat! > I then tried to go the whole way, and get rid of conversion functions > altogether. Being pedantic, what you mean is getting rid of *coercion* functions; = *conversion* functions could never eliminated because by their nature = they are "doing" something (for example, int_of_string constructs a new = integer value based on the string value given to it - you could never = just trick the type system into using the same value for both in a = meaningful way). This is tremendously clean - as long as the types are clearly = documented! The problem is that ocamldoc doesn't let you "document" = coercions (by which I mean that having a conversion function provides = means for the documentation of that particular usage). David