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

limitation on how the typer fills in missing optional arguments #7240

Closed
vicuna opened this issue Apr 25, 2016 · 1 comment
Closed

limitation on how the typer fills in missing optional arguments #7240

vicuna opened this issue Apr 25, 2016 · 1 comment
Assignees

Comments

@vicuna
Copy link

vicuna commented Apr 25, 2016

Original bug ID: 7240
Reporter: @sliquister
Assigned to: @garrigue
Status: resolved (set by @garrigue on 2017-03-15T05:55:16Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 4.02.3
Target version: later
Category: typing
Monitored by: @hcarty

Bug description

The following code is accepted:

# let f g = g ();;
val f : (unit -> 'a) -> 'a = <fun>
# let g1 ?a:_ () = ();;
val g1 : ?a:'a -> unit -> unit = <fun>
# f g1;;
- : unit = ()

so I don't understand why the following isn't:

# let f g = g ~b:1 ();;
val f : (b:int -> unit -> 'a) -> 'a = <fun>
# let g1 ?a:_ ~b:_ () = ();;
val g1 : ?a:'a -> b:'b -> unit -> unit = <fun>
# f g1;;
Error: This expression has type ?a:'a -> b:'b -> unit -> unit
       but an expression was expected of type b:int -> unit -> 'c

This is the behavior documented in http://caml.inria.fr/pub/docs/manual-ocaml/lablexamples.html, but I don't understand what would be problematic with allowing to fill in the missing optional arguments whether what follows are labelled arguments or positional arguments.

Also the behavior of the typer doesn't seem to be the documented behavior, as the documentation says this is correct, but the typer rejects it:

# let f g = g () ();;
val f : (unit -> unit -> 'a) -> 'a = <fun>
# let g1 ?a:_ () () = ();;
val g1 : ?a:'a -> unit -> unit -> unit = <fun>
# let g2 () ?a:_ () = ();;
val g2 : unit -> ?a:'a -> unit -> unit = <fun>
# f g1;;
- : unit = ()
# f g2;;
Error: This expression has type unit -> ?a:'a -> unit -> unit
       but an expression was expected of type unit -> unit -> 'b
@vicuna
Copy link
Author

vicuna commented Mar 15, 2017

Comment author: @garrigue

Concerning your first example, the problem is that, when there are other labeled arguments, the evaluation order becomes hard to establish correctly.
Namely, g1 seems ok, but the following g3 could be a problem:
let g3 ~b = print_endline "g3"; fun ?a () -> ...
Here we would need to generate extra code to ensure that partial applications on b are correctly evaluated.

For your last example, the intent of the documentation is that the optional arguments should come first, for the same reason as above. So g2 cannot be used.

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

2 participants