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=0.4 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE 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 C31E2BC69 for ; Mon, 19 Mar 2007 02:15:16 +0100 (CET) Received: from kurims.kurims.kyoto-u.ac.jp (kurims.kurims.kyoto-u.ac.jp [130.54.16.1]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l2J1FE7s027660 for ; Mon, 19 Mar 2007 02:15:15 +0100 Received: from localhost (orion [130.54.16.5]) by kurims.kurims.kyoto-u.ac.jp (8.13.7/8.13.7) with ESMTP id l2J1F5Hp012142; Mon, 19 Mar 2007 10:15:05 +0900 (JST) Date: Mon, 19 Mar 2007 10:15:00 +0900 (JST) Message-Id: <20070319.101500.03115026.garrigue@math.nagoya-u.ac.jp> To: n8gray@gmail.com Cc: caml-list@inria.fr Subject: Re: [Caml-list] Labels and polymorphism From: Jacques Garrigue In-Reply-To: References: X-Mailer: Mew version 4.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Miltered: at discorde with ID 45FDE422.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; polymorphism:01 listlabels:01 listlabels:01 ocaml:01 semantics:01 semantics:01 compilation:01 compiler:01 semantically:01 inference:01 ocaml:01 partial:01 partial:01 behaviour:01 behaviour:01 From: "Nathaniel Gray" [...] > 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. Sorry for the very late answer... What about your idea. I could like it, but I see two problems. The first one is that (as you point yourself) it requires that labeled arguments come after unlabeled ones. If you look at the labelings in ListLabels, you will see that generally the opposite is true: labeled arguments come first. For instance, with your proposal it would become impossible to write "ListLabels.map l ~f:(fun .........)", which is one of the nice uses of labels. There is a good reason for labeled arguments to come first: they are the ones who provide useful partial applications. And it is generally more efficient to do partial applications in the right order. (Actually, one could argue that in a new language, we could choose a different approach. But OCaml existed before labels, so this cannot be easily changed in an existing language.) The second problem is more fundamental: adding labels to a function cannot be done without breaking compatibility. This is because labels must match exactly when you pass a function as argument to another function. So, while we want to make the use of labels not too intrusive, it is impossible to make them completely transparent. This reduces the relative value of a small increment in non-intrusiveness, as it cannot be perfect anyway. We could of course thing of other approaches, which would allow out-of-order applications while being close to your proposal. But first, a small word on why it is more complicated than it seems at first sight. The difficulty is that we want the semantics not to depend on types. That is, we should define a semantics for application which works without looking at the type of the function applied. This may seems contradictory, as the type must be known for compilation, but this is a highly desirable property in a language where most types are inferred. This may be annoying to have the compiler tell you that some application is not allowed while it is semantically OK, but this would be terrible if it accepted it, but resulted in an undefined behaviour, depending on an hidden behaviour of type inference. Finally, the rationale behind the current strategy is: * keep full compatibility with a semantics where all labels would have to be always written. This semantics was used in early versions of ocaml, and is well understood. * make it less intrusive by allowing ommiting labels in most applications (as long as this can be made compatible with the above semantics.) This explains why this is not _all_ applications. There could be other choices. This one privileges continuity. I don't believe there is an ideal solution, as desired properties vary from one person to another. Jacques Garrigue