caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Nathaniel Gray" <n8gray@gmail.com>
To: "Roland Zumkeller" <roland.zumkeller@gmail.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Labels and polymorphism
Date: Thu, 8 Mar 2007 15:42:10 -0800	[thread overview]
Message-ID: <aee06c9e0703081542o36715b5brfe55a291b56f84c6@mail.gmail.com> (raw)
In-Reply-To: <d02dcb040703081140v734d3633q1b29cf94c9e66cb@mail.gmail.com>

On 3/8/07, Roland Zumkeller <roland.zumkeller@gmail.com> wrote:
> On 08/03/07, Nathaniel Gray <n8gray@gmail.com> wrote:
> > # let f ~x = x;;
> > val f : x:'a -> 'a = <fun>
> > # f ~x:1;;
> > - : int = 1
> > # f 1;;
> > - : x:(int -> 'a) -> 'a = <fun>
>
> 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 = <fun>

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 = <fun>
# 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 = <fun>
# let g ~y = f;;
val g : y:'a -> x:'b -> 'b = <fun>
# 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 -->


  reply	other threads:[~2007-03-08 23:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-08 18:31 Nathaniel Gray
2007-03-08 19:14 ` [Caml-list] " Eric Cooper
2007-03-08 19:40 ` Roland Zumkeller
2007-03-08 23:42   ` Nathaniel Gray [this message]
2007-03-19  1:15     ` Jacques Garrigue
2007-03-19 23:53       ` Nathaniel Gray
2007-03-20  0:51         ` Jacques Garrigue
2007-03-08 23:30 ` skaller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aee06c9e0703081542o36715b5brfe55a291b56f84c6@mail.gmail.com \
    --to=n8gray@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=roland.zumkeller@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).