Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confusing syntax for labelled and optional argument type annotations #7420

Closed
vicuna opened this issue Nov 25, 2016 · 5 comments
Closed

Confusing syntax for labelled and optional argument type annotations #7420

vicuna opened this issue Nov 25, 2016 · 5 comments

Comments

@vicuna
Copy link

vicuna commented Nov 25, 2016

Original bug ID: 7420
Reporter: @johnwhitington
Status: resolved (set by @xavierleroy on 2017-02-19T17:27:02Z)
Resolution: suspended
Priority: normal
Severity: minor
Category: typing

Bug description

Type annotations on labelled or optional arguments in .ml files are thrown away without warning:

let f ?x:int y = y;;

val f : ?x:'a -> 'b -> 'b =

let f ~x:int y = y;;

val f : x:'a -> 'b -> 'b =

The labelled one should be used in the normal way, to restrict the type and the optional one should be rejected, not being an option type, surely? It seems odd to silently drop them.

Additional information

For reference, for anyone as easily confused as me, here is a .mli/.ml pair which typechecks for such a function

val f : ?x:int -> 'a -> 'a

let f ?(x : int option) y = y

The option-ness of the type of 'x' is implicit in the .mli, explicit in the .ml.

@vicuna
Copy link
Author

vicuna commented Nov 25, 2016

Comment author: @johnwhitington

The first definition is properly rejected by ocamlc -i:

$cat labels.ml
let f ?x:int y = y;;

$ ocamlc -i labels.ml
File "labels.ml", line 1, characters 8-13:
Error: This pattern matches values of type int
but a pattern was expected which matches values of type 'a option

So perhaps this is just a top-level issue.

@vicuna
Copy link
Author

vicuna commented Nov 25, 2016

Comment author: @lpw25

This is merely a confusion of syntax: you're actually specifying the name of the parameter with that syntax rather than its type. For example,

let f ~x:int y = int;;
val f : x:'a -> 'b -> 'a =

To specify a type you should use:

let f ~(x:int) y = y;;

val f : x:int -> 'a -> 'a =

It's an unfortunate similarity, but I don't think anything can be done at this point.

@vicuna
Copy link
Author

vicuna commented Nov 25, 2016

Comment author: @johnwhitington

Of course. Thanks.

@vicuna
Copy link
Author

vicuna commented Nov 25, 2016

Comment author: @gasche

It's an unfortunate similarity, but I don't think anything can be done at this point.

That sounds awkward, but maybe we could warn if the identifier chosen happens to be one of the built-in non-parameterized types of the language? (I don't think that int, char or bool are commendable identifier names anyway.)

@vicuna
Copy link
Author

vicuna commented Feb 19, 2017

Comment author: @xavierleroy

Suspending this PR by lack of ideas on what could be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant