caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Applying labeled function without a label
@ 2013-07-10 13:48 Ivan Gotovchits
  2013-07-10 15:02 ` John Carr
  2013-07-10 15:05 ` Alain Frisch
  0 siblings, 2 replies; 5+ messages in thread
From: Ivan Gotovchits @ 2013-07-10 13:48 UTC (permalink / raw)
  To: caml-list



Please, can someone explain the reason behind the following behaviour:


# let f ~a = a;;
val f : a:'a -> 'a = <fun>

if I apply function f, omiting the label, instead of an error I'll get:

# f 12;;
- : a:(int -> 'a) -> 'a = <fun>

... a function that accepts a labeled arguments, that is a function from int
to 'a, and returns a result of this function:

# f 12 ~a:(fun x -> x + 1);;
- : int = 13

and even more, if I apply it to more unlabled arguments:

# f 1 2 3 4 5;;
- : a:(int -> int -> int -> int -> int -> 'a) -> 'a = <fun>

It is very confusing...

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Applying labeled function without a label
  2013-07-10 13:48 [Caml-list] Applying labeled function without a label Ivan Gotovchits
@ 2013-07-10 15:02 ` John Carr
  2013-07-10 15:13   ` r.3
  2013-07-10 15:05 ` Alain Frisch
  1 sibling, 1 reply; 5+ messages in thread
From: John Carr @ 2013-07-10 15:02 UTC (permalink / raw)
  To: Ivan Gotovchits; +Cc: caml-list


A function with an unconstrained type variable on the right hand side
of its type can potentially take an unlimited number of arguments.

You have the equivalent of a shift-reduce conflict in a grammar.  The
compiler can choose to reduce (apply f to the argument) or shift (save
the arguments waiting for more).  The choice to shift seems odd but
there may be a situation where it is useful.

If your function were defined

let f ~a = a + 0

it would be monomorphic. The compiler would match an unlabeled argument
with parameter a.

> 
> 
> Please, can someone explain the reason behind the following behaviour:
> 
> 
> # let f ~a = a;;
> val f : a:'a -> 'a = <fun>
> 
> if I apply function f, omiting the label, instead of an error I'll get:
> 
> # f 12;;
> - : a:(int -> 'a) -> 'a = <fun>
> 
> ... a function that accepts a labeled arguments, that is a function from int
> to 'a, and returns a result of this function:
> 
> # f 12 ~a:(fun x -> x + 1);;
> - : int = 13
> 
> and even more, if I apply it to more unlabled arguments:
> 
> # f 1 2 3 4 5;;
> - : a:(int -> int -> int -> int -> int -> 'a) -> 'a = <fun>
> 
> It is very confusing...
> 
> -- 
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Applying labeled function without a label
  2013-07-10 13:48 [Caml-list] Applying labeled function without a label Ivan Gotovchits
  2013-07-10 15:02 ` John Carr
@ 2013-07-10 15:05 ` Alain Frisch
  1 sibling, 0 replies; 5+ messages in thread
From: Alain Frisch @ 2013-07-10 15:05 UTC (permalink / raw)
  To: Ivan Gotovchits, caml-list

On 07/10/2013 03:48 PM, Ivan Gotovchits wrote:
>
>
> Please, can someone explain the reason behind the following behaviour:
>
>
> # let f ~a = a;;
> val f : a:'a -> 'a = <fun>
>
> if I apply function f, omiting the label, instead of an error I'll get:
>
> # f 12;;
> - : a:(int -> 'a) -> 'a = <fun>
>
> ... a function that accepts a labeled arguments, that is a function from int
> to 'a, and returns a result of this function:

If you apply f without the labeled argument, if means that the 'a in the 
type scheme "a:'a -> 'a" must be a function type accepting 12 (because 
you pass it the value 12).  So 'a is unified with int -> 'b, and the 
type of "f 12" is thus "a:(int -> 'b) -> 'b".

The point to be noted is that omitted labelled arguments are accepted by 
the type-checker and result in a partial application of the function. 
This is different from optional arguments (when omitted in a function 
application with non-labelled arguments, they are assumed to be missing 
and don't result in a partial application).

FWIW, LexiFi's version of OCaml changes this behavior.  We have decided 
that such omitted labelled arguments should be assumed to be really 
missing and thus result in an error, not a partial application.  So in 
our version, we have:

# let f ~a = a;;
val f : a:'a -> 'a = <fun>
# f 12;;
Error: Missing labeled argument ~a in this function call.


This change tends to give better error messages and avoid some 
confusion; it was also necessary to support another local change: 
implicit arguments, which are non-optional labelled arguments that can 
be synthesized by the compiler based on their type.

-- Alain


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Applying labeled function without a label
  2013-07-10 15:02 ` John Carr
@ 2013-07-10 15:13   ` r.3
  0 siblings, 0 replies; 5+ messages in thread
From: r.3 @ 2013-07-10 15:13 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 1511 bytes --]


On 10/07/2013 17:02, John Carr wrote: 

A function with an unconstrained type variable on the right hand side
of its type can potentially take an unlimited number of arguments.

You have the equivalent of a shift-reduce conflict in a grammar.  The
compiler can choose to reduce (apply f to the argument) or shift (save
the arguments waiting for more).  The choice to shift seems odd but
there may be a situation where it is useful.

If your function were defined

let f ~a = a + 0

it would be monomorphic. The compiler would match an unlabeled argument
with parameter a. 


That is to say : 
# let f ~a = a + 0;; 
val f : a:int -> int = <fun> 
# f 12;; 
- : int = 12 


<blockquote>

<blockquote>
Please, can someone explain the reason behind the following behaviour:


# let f ~a = a;;
val f : a:'a -> 'a = <fun>

if I apply function f, omiting the label, instead of an error I'll get:

# f 12;;
- : a:(int -> 'a) -> 'a = <fun>

... a function that accepts a labeled arguments, that is a function from int
to 'a, and returns a result of this function:

# f 12 ~a:(fun x -> x + 1);;
- : int = 13

and even more, if I apply it to more unlabled arguments:

# f 1 2 3 4 5;;
- : a:(int -> int -> int -> int -> int -> 'a) -> 'a = <fun>

It is very confusing...

-- 
Caml-list mailing list.  Subscription management and archives: https://sympa.inria.fr/sympa/arc/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs 
</blockquote>

</blockquote>


[-- Attachment #2: Type: text/html, Size: 2384 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Applying labeled function without a label
       [not found] <51DD79B6.9030306@libertysurf.fr>
@ 2013-07-10 15:12 ` r.3
  0 siblings, 0 replies; 5+ messages in thread
From: r.3 @ 2013-07-10 15:12 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 2077 bytes --]


I agree it is very confusing... 


On 10/07/2013 15:48, Ivan Gotovchits wrote: 

Please, can someone explain the reason behind the following behaviour:


# let f ~a = a;;
val f : a:'a -> 'a = <fun> 

You are defining 'f', a function that waits for a labeled argument called 'a' and that will send back itself. 


<blockquote>
if I apply function f, omiting the label, instead of an error I'll get:

# f 12;;
- : a:(int -> 'a) -> 'a = <fun> 
</blockquote>
yes, very confusing. 'f 12' is still not applied (see at the end, it is maybe a problem in ocaml). It is still waiting for the label '~a'. once the label is given, 'f ~a' will be able to give back the result, and then apply it to '12'. So the labelled argument should be a function from an int to something, in order to be applied to '12'. That is what you are doing next : 


<blockquote>
... a function that accepts a labeled arguments, that is a function from int
to 'a, and returns a result of this function:

# f 12 ~a:(fun x -> x + 1);;
- : int = 13 
</blockquote>

What is confusing is that f is applied to ~a, not to 12 directly (because of labels properties). 
f ~a => (fun x -> x+1) 
then 
(fun x -> x +1) 12 => 13 



<blockquote>
and even more, if I apply it to more unlabled arguments:

# f 1 2 3 4 5;;
- : a:(int -> int -> int -> int -> int -> 'a) -> 'a = <fun> 
</blockquote>
This is same behaviour : waiting for a labelled argument that will be able to deal with 5 integers. 


<blockquote>
It is very confusing... 
</blockquote>

I agree it is confusing. And there is something strange : 

The doc says : 

"As an exception to the above parameter matching rules, if an application is total (omitting all optional arguments), labels may be omitted. In practice, many applications are total, so that labels can often be omitted." 
# let f ~x ~y = x - y;; val f : x:int -> y:int -> int = <fun> # f 3 2;; - : int = 1 
But in your case, when you do "f 12", the application is total, and thus it should be applied and give '12'. But it is not applied. This is an inconsistency in the documentation. 

William 

[-- Attachment #2: Type: text/html, Size: 3426 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-07-10 15:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-10 13:48 [Caml-list] Applying labeled function without a label Ivan Gotovchits
2013-07-10 15:02 ` John Carr
2013-07-10 15:13   ` r.3
2013-07-10 15:05 ` Alain Frisch
     [not found] <51DD79B6.9030306@libertysurf.fr>
2013-07-10 15:12 ` r.3

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).