Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006039OCamlOCaml generalpublic2013-06-12 16:142014-08-22 11:00
Reportermottl 
Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
StatusacknowledgedResolutionopen 
PlatformOSOS Version
Product Version4.00.1 
Target VersionFixed in Version 
Summary0006039: Syntax improvement for functor type definitions
DescriptionWhy 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.
Tagspatch
Attached Filespatch file icon 0001-functor-syntax.patch [^] (2,840 bytes) 2013-06-19 11:48 [Show Content]

- Relationships

-  Notes
(0009557)
doligez (administrator)
2013-06-19 11:48

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.
(0009580)
mottl (reporter)
2013-06-19 21:54

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.
(0009584)
xleroy (administrator)
2013-06-20 09:54

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).
(0009587)
Julien Signoles (reporter)
2013-06-20 14:31

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.
(0009591)
mottl (reporter)
2013-06-20 15:29

@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.
(0012040)
doligez (administrator)
2014-08-21 11:50

Note: the part Xavier agrees with (curried functor types) is now implemented.
(0012043)
mottl (reporter)
2014-08-21 17:49

I've just tried the 4.02 beta, and the new syntax seems to be working fine.

- Issue History
Date Modified Username Field Change
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


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker