Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] labels and optional arguments in 3.06
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@k...>
Subject: Re: [Caml-list] labels and optional arguments in 3.06
From: Chris Hecker <checker@d6.com>

> The new optional label semantics seem to work pretty well for my
> normal usage, however I've run across one thing I'd like to do that
> doesn't seem to work (and a warning I don't understand):
> 
> > # let f ?(a = 1.0) ~b ~c = a *. b *. c;;
> > Characters 12-15:
> > Warning: This optional argument cannot be erased
> >   let f ?(a = 1.0) ~b ~c = a *. b *. c;;
> >               ^^^
> > val f : ?a:float -> b:float -> c:float -> float = <fun>
> 
> First question:  what is this warning?

It says that since there is no unlabeled argument after this optional
one, there is no way to "erase" it using normal rules. This is not
100% true with the new semantics, as passing all other arguments
without labels will do the job, but still this is not a proper
labelling.

> Second question:  I'd like to be able to call f with or without
> specifying the optional argument, without labels:
> 
> > # f;;
> > - : ?a:float -> b:float -> c:float -> float = <fun>
> > # f 2.0 4.0;;
> > - : float = 8.
> 
> works fine,

Yes, so the above (old) warning is not correct.
Maybe I can drop it altogether: there shall just be a non-optional
argument after an optional one, labelled or not.

> > # f ~a:2.0 2.0 4.0;;
> > Characters 9-12:
> >   f ~a:2.0 2.0 4.0;;
> >            ^^^
> > Expecting function has type b:float -> c:float -> float
> > This argument cannot be applied without label
> 
> doesn't work.

Indeed: the new rule is that if you pass n unlabelled arguments, and
there are exactly n non-optional argument to your function, this is
acceptable, but in all other cases you get the strict labelled
behaviour. So as soon as you write a label you must write them all.

A rule which would allow to mix labelled and unlabelled arguments in
an application could be extremely confusing. Consider for instance
val f : ~a:float -> ?a:float -> float -> float
# f ~a:1.0 2.0 3.0;;
What is the meaning of the above application?
If we apply the labelled rule, we get 1.0 for the first, then 2.0 for
the third (erasing the second), and 3.0 fails as an extra argument.
If we apply a new mixed unlabelled rule, we get 2.0 for the first, 1.0
for the second, and 3.0 for the third.
So we should probably refuse such an application.
But then how could we accept
# f 2.0 ~a:1.0 3.0;;
which is only a permutation of the previous one, and we expect such
labelled permutations of arguments to be always valid?

> I'd like to be able to use ~b and ~c for interface
> documentation, but not be forced to use them, and have ?a be an
> optional parameter.  This
> 
> > # f ~a:2.0 ~b:2.0 ~c:4.0;;
> > - : float = 16.
> 
> works, of course, but it's really verbose.

You can write

# (f ~a:2.0) 2.0 4.0;;

The parenthesis creates staged applications, one labelled-style and
the other unlabelled-style.

---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners