|Anonymous | Login | Signup for a new account||2016-12-08 08:57 CET|
|Main | My View | View Issues | Change Log | Roadmap|
|View Issue Details|
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0006039||OCaml||OCaml general||public||2013-06-12 16:14||2016-12-07 18:05|
|Target Version||Fixed in Version||4.02.0|
|Summary||0006039: Syntax improvement for functor type definitions|
|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) -> ...
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.
|Attached Files||0001-functor-syntax.patch [^] (2,840 bytes) 2013-06-19 11:48 [Show Content]|
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.
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.
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).
Julien Signoles (reporter)
|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.|
@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
val f : int -> 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.
|Note: the part Xavier agrees with (curried functor types) is now implemented.|
|I've just tried the 4.02 beta, and the new syntax seems to be working fine.|
|In which case this issue can be closed.|
|2013-06-12 16:14||mottl||New Issue|
|2013-06-19 11:48||doligez||Note Added: 0009557|
|2013-06-19 11:48||doligez||Status||new => confirmed|
|2013-06-19 11:48||doligez||Target Version||=> 4.02.0+dev|
|2013-06-19 11:48||doligez||File Added: 0001-functor-syntax.patch|
|2013-06-19 21:54||mottl||Note Added: 0009580|
|2013-06-20 09:54||xleroy||Note Added: 0009584|
|2013-06-20 14:31||Julien Signoles||Note Added: 0009587|
|2013-06-20 15:29||mottl||Note Added: 0009591|
|2013-07-12 18:15||doligez||Target Version||4.02.0+dev => 4.01.1+dev|
|2013-12-16 16:42||doligez||Tag Attached: patch|
|2014-05-25 20:24||doligez||Target Version||4.01.1+dev => 4.02.0+dev|
|2014-08-21 11:50||doligez||Note Added: 0012040|
|2014-08-21 11:50||doligez||Status||confirmed => feedback|
|2014-08-21 11:50||doligez||Target Version||4.02.0+dev =>|
|2014-08-21 17:49||mottl||Note Added: 0012043|
|2014-08-21 17:49||mottl||Status||feedback => new|
|2014-08-22 11:00||shinwell||Status||new => acknowledged|
|2016-12-07 18:05||shinwell||Note Added: 0016753|
|2016-12-07 18:05||shinwell||Status||acknowledged => resolved|
|2016-12-07 18:05||shinwell||Fixed in Version||=> 4.02.0|
|2016-12-07 18:05||shinwell||Resolution||open => fixed|
|2016-12-07 18:05||shinwell||Assigned To||=> shinwell|
|Copyright © 2000 - 2011 MantisBT Group|