From mboxrd@z Thu Jan 1 00:00:00 1970 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 p9HDrajg027619 for ; Mon, 17 Oct 2011 15:53:41 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am8BAJoynE6BryEpkWdsb2JhbABDhHWWGY1aIgEBAQEJCwsHFAQhgW4BAQQBIwRFDQULCQIYAgImAgIfHhoGE4d/oh2RdIEwhUSBFASMIZkx X-IronPort-AV: E=Sophos;i="4.69,359,1315173600"; d="scan'208";a="124441514" Received: from smtp1.u-psud.fr ([129.175.33.41]) by mail1-smtp-roc.national.inria.fr with ESMTP; 17 Oct 2011 15:53:31 +0200 Received: from smtp1.u-psud.fr (localhost [127.0.0.1]) by localhost (MTA) with SMTP id DE638256249; Mon, 17 Oct 2011 15:53:30 +0200 (CEST) Received: from ext.lri.fr (ext.lri.fr [129.175.15.4]) by smtp1.u-psud.fr (MTA) with ESMTP id 933E9256353; Mon, 17 Oct 2011 15:53:30 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by ext.lri.fr (Postfix) with ESMTP id 93F804079E; Mon, 17 Oct 2011 15:53:30 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at lri.fr Received: from ext.lri.fr ([127.0.0.1]) by localhost (ext.lri.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8jBHaA-QLL0B; Mon, 17 Oct 2011 15:53:30 +0200 (CEST) Received: from lri.fr (dhcp144.dmi.ens.fr [129.199.97.144]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by ext.lri.fr (Postfix) with ESMTPSA id 69E0D40788; Mon, 17 Oct 2011 15:53:30 +0200 (CEST) Date: Mon, 17 Oct 2011 15:53:35 +0200 From: AUGER Cedric To: Matej =?UTF-8?B?S2/FocOtaw==?= Cc: caml-list@inria.fr Message-ID: <20111017155335.48595755@lri.fr> In-Reply-To: <4E9B3D66.6080203@fiit.stuba.sk> References: <4E9B27A1.5070309@fiit.stuba.sk> <4E9B3D66.6080203@fiit.stuba.sk> X-Mailer: Claws Mail 3.7.9 (GTK+ 2.24.5; i386-portbld-freebsd8.1) Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p9HDrajg027619 X-Validation-by: cedric.auger@lri.fr Subject: Re: [Caml-list] Ocaml: typing by name vs. typing by structure Le Sun, 16 Oct 2011 22:24:06 +0200, Matej Košík a écrit : > On 10/16/2011 09:24 PM, Gabriel Scherer wrote: > > If record were structurally typed, there would be an ambiguity as > > to, for example, what this function mean: > > > > let access_foo t = t.foo > > > > What would the type of `access_foo` be ? { foo : 'a } -> 'a ? > > { foo : 'a; bar : 'b } -> 'a ? > > { foo : 'a } -> 'a > > seems plasible > > > Should `access_foo { foo = 1 }` be typable? And `access_foo { foo = > > 1; bar = true }` ? > > > > In this situation, you want record subtyping. This get more > > complicated than the relatively simple OCaml records. > So, now, how would you type: let f x = x.bar + x.foo let g x = x.bar + x.foobar ? -> typing error for g, since "x is of type {bar:int; foo:int} while it expected to be of type {bar:int; foobar:int} -> parse all the file to find out that the whished type is: "{foo:int; bar:int; foobar:int}" and thus leading to: 1. modularity break, since fields could be defined/used out of the file 2. extra care when using fields to avoid doing stuff like: let f x = x.bar + x.foo let g x = x.bsr + x.foobar where bsr is a typo, leading to disjoint types/extra field making data inconstistent. -> other stuff For me, only the first is acceptable (or maybe otherstuff?), and so you need to declare the type somewhere (and you lost your ability to hide type definitions) or ensure that the first function uses all its arguments. Furthermore, it is always wishable for someone reading your code to have some place where they can find ALL fields, to know their names, or understand what it represents. > This may be too troublesome to support but I guess it is plausible > language change and it would enable additional Ocaml terseness. Let > me clarify. > > At the moment, it is not possible to do this: > > type t = {l1:int} * {l2:int};; > > It is a syntax error. We are forced to do it gradually: > > type t1 = { l1 : int; } > type t2 = { l2 : int; } > type t = t1 * t > > This is somewhat cumbersome. > > Similarly, you cannot do this > > type t = A of {l1:int} > | B of {l2:float} > | C of {l1:int; l2:float} > > Only this works: > > type t1 = { l1 : int} > type t2 = { l2 : float} > type t3 = { l1 : int; l2: float} > type t = A of t1 > | B of t2 > | C of t3 > In fact I guess it doesn't work due to "field collision": you cannot use the same field name for different records. Note that your first example is not pertinent to me, since I see no point in naming structures which have only one field, so I would prefer type t = {l1:int;l2:int} or type t = int * int for the sum types, that means, you may have difficulties to do: let f x = match x with | A x1 -> g x1 | B x2 -> h x2 | C x3 -> i x3 since g, h and i won't have type, as x1, x2 and x3 won't have one either. > We were forced to introduce three superfluous type-names [t1;t2;t3]. > How would you feel if you were forced to do that for every tuple-type? > > Sometimes tuples are not ideal > (when they have lots of members) I would rather say "when they have lots of members sharing the same type" > Records are better in those cases because you can access elements by > their label and when you construct records with lots of fields, the > labels clarify which field has what meaning. But switching from > tuples to records is not smooth. What could be gained in readability > (labeled fields) is lost by cluttering the program by auxiliary > record type definitions. > > > In fact, OCaml > > has structurally typed structures with named fields : objects > > > > # let access_foo t = t#foo;; > > val access_foo : < foo : 'a; .. > -> 'a = > > # access_foo (object method foo = 1 method bar = true end);; > > - : int = 1 > > Interesting. > > > > > Tuples don't have this issue as they don't have an universal > > accessor function : there is no way to get the first element of a > > tuple whatever its width is. Therefore, all tuples manipulation > > make the structure concrete, and structural subtyping comes at no > > complexity cost ... if you accept the absence of universal > > accessors. SML has them (#1 #2 etc.) and I'm not sure how they > > handle this. >