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
Syntax improvement for functor type definitions #6039
Comments
Comment author: @damiendoligez Here is a patch against trunk(4.02). Before we commit it, I'll need a review and a discussion about the feature. I'm a bit worried that this syntax makes it look like we are defining a module type constructor (a mapping from modules to module types) rather than a functor module type (the type of a mapping from modules to modules). If other people think that's not a big problem, we'll apply the patch. We'll re-launch the discussion after the 4.01.0 release. |
Comment author: @mmottl I see your point concerning the mapping from modules to module types, but there is currently no syntax for implementing the latter anyway. People will usually use workarounds like: module Make_module_type (Args : ARGS) = struct module type S = sig ... end end I hence don't think anybody would confuse the new syntax as representing module type constructors. Not saying it wouldn't be nice to have some sort of syntactic sugar for the latter, too, e.g. something of the sort: module Make_module_type (Args : ARGS) = sig ... end Then, of course, I might worry about how to avoid ambiguities in signatures. No rush with this feature, I think improvements to the module system should be carefully discussed. In my experience the module system is already impressively expressive, but a little unwieldy to use at times. |
Comment author: @xavierleroy Waitaminute. I am uncomfortable with the proposed syntactic sugar. Let's make the parallel functor = function. In a signature, a function is declared like this: val f: int -> bool -> string What you're proposing is akin to val f (x: int) (y: bool) = string First, the "=" makes no sense: this is a declaration, not a definition. But even with "=" replaced by ":" val f (x: int) (y: bool) : string I don't see much of an improvement in clarity or otherwise w.r.t. val f: int -> bool -> string Going back to functors and the module level, there is already a lot of confusion in some users's minds about definition versus declaration. I'm afraid that making functor declarations "more like" functor definitions isn't going to help. The one part of the suggestion I can agree with is the curried functor type functor (X: S1) ... (Y: Sn) -> S which is indeed syntactically lighter, yet consistent with the view above (declarations should look different from definitions). |
Comment author: Julien Signoles Here are my 2 cents: I agree with Xavier. Also, that's true that "functor ... -> ..." is an heavy syntax and a better one could have been chosen some years ago ;-) but, from my own experience, it is not used very often. The only use case I have in mind is higher-order (uncurried) functors which are pretty rare. |
Comment author: @mmottl @xLeroy: the parallel seems more like a comparison to the signature of functors, which already is: module F (X : Int) (Y : Int) : String But the suggestion was to improve definitions of functor module types, which seems conceptually more similar to type definitions. Still, I agree that the "=" looks more like a definition and should hence follow right after the defined name. So how about this: module type F = (X : Int) -> (Y : Bool) -> String This basically means just dropping the functor keyword. I don't see why it should ever be useful in a signature anyway. We also don't use "fun" in type definitions: type f = fun int -> fun bool -> string A more consistent though minimally longer way to define functors in signatures would then have been (compare to the function definition): module F : (X : Int) -> (Y : Bool) -> String The above also seems more suggestive of the fact that currying works with modules, too. The "functor" keyword would ideally only appear in structures to pass anonymous functors to a higher-order functor as in: module Res = Apply (functor (X : S) -> struct ... end) Thinking about what I'd really prefer language-wise, it's probably syntactic consistency rather than utmost syntactic brevity. The above syntax changes would seem backwards-compatible and cleaner, but I'd admittedly be reluctant to add syntax alternatives that would likely confuse beginners even more. OTOH, their struggles with the module system are probably not so much syntactic anyway so maybe we can at least drop the requirement for the "functor" keyword in module type definitions for a start. It really feels quite unnecessary there. |
Comment author: @damiendoligez Note: the part Xavier agrees with (curried functor types) is now implemented. |
Comment author: @mmottl I've just tried the 4.02 beta, and the new syntax seems to be working fine. |
Comment author: @mshinwell In which case this issue can be closed. |
Original bug ID: 6039
Reporter: @mmottl
Assigned to: @mshinwell
Status: resolved (set by @mshinwell on 2016-12-07T17:05:28Z)
Resolution: fixed
Priority: normal
Severity: feature
Version: 4.00.1
Fixed in version: 4.02.0
Category: ~DO NOT USE (was: OCaml general)
Tags: patch
Monitored by: "Julien Signoles" @hcarty @mmottl
Bug description
Why is it actually that we need to define:
module type Foo = functor (X : sig end) -> sig end
Instead of the syntactically lighter and more intuitive:
module type Foo (X : sig end) = sig end
If a functor takes multiple arguments, we also need to write:
module type Foo = functor (X : sig end) -> functor (Y : sig end) -> ...
Instead of:
module type Foo = functor (X : sig end) (Y : sig end) -> ...
Or the most readable one:
module type Foo (X : sig end) (Y : sig end) = ...
Module definitions in signatures already allow syntax similar to the above:
module Foo (X : sig end) : sig end
Anonymous function definitions also support a more concise syntax:
fun x y -> ...
Instead of having to write:
fun x -> fun y -> ...
This makes the current syntax somewhat irregular when it comes to functor definitions. I'm not sure such a syntax improvement could break backward-compatibility in the parser, but probably not. Maybe a handful of CamlP4 macros might require a fix, but this would likely be straightforward.
File attachments
The text was updated successfully, but these errors were encountered: