This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

Labels and polymorphism
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
 Date: 2007-03-19 (01:15) From: Jacques Garrigue Subject: Re: [Caml-list] Labels and polymorphism
From: "Nathaniel Gray" <n8gray@gmail.com>
[...]
> 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