From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.1 required=5.0 tests=AWL,SPF_SOFTFAIL autolearn=disabled version=3.1.3 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 063E7BB84 for ; Tue, 12 Aug 2008 23:05:15 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ah4DAGuXoUip5TxXiGdsb2JhbACRcQEBAQ8gnlaGXkCBUg X-IronPort-AV: E=Sophos;i="4.32,197,1217800800"; d="scan'208";a="15946671" Received: from gateway0.eecs.berkeley.edu ([169.229.60.87]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 12 Aug 2008 23:05:13 +0200 Received: from [10.0.1.5] (136-152-208-32.VPN.Berkeley.EDU [136.152.208.32]) (authenticated bits=0) by gateway0.EECS.Berkeley.EDU (8.14.3/8.13.5) with ESMTP id m7CL52N7021886 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Tue, 12 Aug 2008 14:05:05 -0700 (PDT) In-Reply-To: <200808102038.40534.jon@ffconsultancy.com> References: <200808102038.40534.jon@ffconsultancy.com> Mime-Version: 1.0 (Apple Message framework v753.1) Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed Message-Id: Cc: caml-list@yquem.inria.fr Content-Transfer-Encoding: 7bit From: Brighten Godfrey Subject: Re: [Caml-list] Record field label locality Date: Tue, 12 Aug 2008 14:03:46 -0700 To: Jon Harrop X-Mailer: Apple Mail (2.753.1) X-Spam: no; 0.00; locality:01 ocaml:01 nodes:01 node:01 avoided:01 compiler:01 nodes:01 unambiguous:01 ocaml:01 annotations:01 annotations:01 syntax:01 inference:01 compiler:01 inference:01 On Aug 10, 2008, at 12:38 PM, Jon Harrop wrote: > On Sunday 10 August 2008 11:04:37 Brighten Godfrey wrote: >> Hi, >> >> Here's something that I've wondered about for years; maybe someone >> here can enlighten me. One of the few major annoyances in OCaml code >> style is that if I define a record in one module, say a Graph module: >> >> type t = { >> nodes : node_t array; >> } >> >> then when I use it in another module, say with a graph variable `g', >> then I have to write `g.Graph.nodes' rather than `g.nodes'. >> >> I can understand why a record field label has to be uniquely >> identified. But can't the explicit naming of the Graph module >> usually be avoided, since the compiler will know that `g' is a >> `Graph.t'? For example if I write something like >> >> let g : Graph.t = make_graph () in >> g.nodes >> >> it seems to me that on the second line, the type of `g' and hence the >> meaning of `g.nodes' is unambiguous. > > Although this is a topic of debate and is even something that F# > has done > differently in exactly the way you describe for the reason you > describe, I > would certainly not call it a "major annoyance" in OCaml and, in > fact, I > would not even describe the alternative as "better". > > In correct OCaml code, function bodies basically don't care what type > annotations appear above them, including in the function > definition. This is > very useful because it makes the code compositional. The biggest > problem with > the "solution" you refer to is that code is no longer compositional > because > the body of a function now relies upon the type annotations in the > function > definition that it came from in order to be correct: move the body > expression > to another location that does not happen to be preceeded by the same > annotations and it will no longer compile. I think I see what you're getting at. Is it possible to define compositionality as follows?: "Removing a type annotation from correct OCaml code results in correct OCaml code." I would claim that the current syntax (`g.Graph.nodes' in the above example) is effectively a type annotation that permits the type inference that `g' is a `Graph.t'. The annoying bit is that you are required to use every single time you use a record in `g'. I understand this is not the way the compiler views it. But it's the way I think about it when I'm programming and I suspect many others are in the same situation. Actually, what I want seems to be the way OCaml treats methods in objects: given an object, you can name the method directly without mentioning its module. I can write a function let f x = x#some_method "argument" where `x' might be an object defined in another module, or locally. Why can't records be handled like this? > Moreover, you have created a > stumbling block for users who are new to type inference (currently > almost all > newbies) because the error messages they get are unexpected and > totally > unnecessary. Finally, if you had just defined a local record type > with a > field of the same name then your type annotation must shadow it > with the > field from the Graph module, leading to even more obscure errors. I'm not sure why the error messages must necessarily be confusing. I can see shadowing being confusing, but that can happen already. Thanks very much for your reply! ~Brighten Godfrey