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.0 required=5.0 tests=AWL,SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id C031BBC69 for ; Fri, 9 Mar 2007 00:42:13 +0100 (CET) Received: from wr-out-0506.google.com (wr-out-0506.google.com [64.233.184.228]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l28NgBbj006606 for ; Fri, 9 Mar 2007 00:42:12 +0100 Received: by wr-out-0506.google.com with SMTP id i30so1056741wra for ; Thu, 08 Mar 2007 15:42:11 -0800 (PST) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=GC3CENMdsGlf+ua20+BkHALraqAA7Y4FlNnTlYcyXVssvBPDFLMiB837j927rKXZ/rOeFJm9gEYlvP3+qgASOFH7A1T7yFqtyWYyDEdWEZ9o8xVNquE0OMFrmVGhQA+yBI6YQJQllKJAqIn3cbtnni6WltmsIsS1vHi33MCusws= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=jLtX+zOM7iU1EWMJxjuwgXUN7TwJPbn7LVkKu6ZYsaeAKOkC+SHqmnywbK6yeVoGReJs2y7UPSqY5lEIJtx3T0xmA6dUqn58TJKjdYrOHl8/NDw6syCl7BtJQLp7RDOAQaJGuYw2TfUOJjeb8nWeu3GuGmlt+TVOiyVgFj4dIik= Received: by 10.114.25.3 with SMTP id 3mr326134way.1173397330758; Thu, 08 Mar 2007 15:42:10 -0800 (PST) Received: by 10.115.54.13 with HTTP; Thu, 8 Mar 2007 15:42:10 -0800 (PST) Message-ID: Date: Thu, 8 Mar 2007 15:42:10 -0800 From: "Nathaniel Gray" To: "Roland Zumkeller" Subject: Re: [Caml-list] Labels and polymorphism Cc: caml-list@inria.fr In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: X-j-chkmail-Score: MSGID : 45F09F53.000 on discorde : j-chkmail score : X : 0/20 1 0.000 -> 1 X-Miltered: at discorde with ID 45F09F53.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; polymorphism:01 val:01 ocaml:01 val:01 ocaml:01 wrote:01 wrote:01 imho:01 partial:01 partial:01 typing:01 caml-list:01 functions:01 int:01 int:01 On 3/8/07, Roland Zumkeller wrote: > On 08/03/07, Nathaniel Gray wrote: > > # let f ~x = x;; > > val f : x:'a -> 'a = > > # f ~x:1;; > > - : int = 1 > > # f 1;; > > - : x:(int -> 'a) -> 'a = > > The "1" is assumed to be an argument to "f ~x:a" (where "a" is yet to > be given). Therefore "f ~x:a" must be of type "int -> ...". Now "f > ~x:a" is of the same type as (and here actually reduces to) "a". > Hence this type for the x-labeled argument. > > Perhaps looking at this might help, too: > # f 1 1 1;; > - : x:(int -> int -> int -> 'a) -> 'a = Ok, I think maybe I've got it. The problem is the equivalence between: let f ~x ~y = ... and let f ~x = (fun ~y -> ... ) Or in other words, you have to understand that all functions in ocaml have just one parameter (at least as far as the type system is concerned), so "total application" is tricky to figure out. The more enlightening example, IMHO, is this one: # let f ~x = x;; val f : x:'a -> 'a = # f 10 ~x:(fun x -> x+1);; - : int = 11 In a multi-argument-function world the second line makes no sense. Labeled arguments should allow you to rearrange the (multiple) arguments of the current application, but not interleave them with arguments from upcoming applications! Enlightenment blossoms when you realize that that's actually the thing that labeled arguments *do* allow you to do. Another helpful example: # let f ~x = x;; val f : x:'a -> 'a = # let g ~y = f;; val g : y:'a -> x:'b -> 'b = # g ~x:3 ~y:5;; - : int = 3 > Now you ask, why are things as they are? Why can't OCaml guess that > the "1" was meant for the label "x"? > > Probably it could, but with such a typing rule we would have to write > "(fun ~x:a -> f ~x:a 1)" for what is currently "f 1" (partial > application would be essentially lost here). In contrast, becoming > able to write "f x" instead of "f ~x:1" seems not enough of a gain to > compensate this. You could do it by using the rule that applying an unlabeled argument in a labeled context always binds to that label, but applying a labeled argument in an unlabeled context (or one where the labels don't match) defers the application until the label is found. (Maybe this is what you're hinting at?) So if you define f like this: let f a b ~c x ~y ~z = z Then you could apply it in one of these ways: f 1 2 3 4 5 6 f 1 2 3 4 ~z:6 ~y:5 f ~c:3 ~z:6 1 2 4 5 But not this way: f 1 2 4 ~c:3 5 6 (* Too late -- c is already bound to 4 *) f 1 2 ~y:5 4 ~c:3 6 (* Ditto *) As a practical matter you would probably want to label a suffix of your arguments for maximum flexibility. You would lose the ability to do *some* (dare I say unimportant?) partial applications, but this approach seems much more intuitive to me. Mainly it has the advantage that adding labels to a function would never break existing calls to that function. This property seems highly desirable to me -- so desirable that I'm downright astonished it isn't already true. Thanks for helping, -n8 -- >>>-- Nathaniel Gray -- Caltech Computer Science ------> >>>-- Mojave Project -- http://mojave.cs.caltech.edu -->