Parentheses around arguments in functor application

I am curious about why functor application needs parentheses. Currently, if F is a functor applying to some module M, then we need to write F(M) instead of just F M. However, it seems the grammar can still be made unambiguous even with all the language extensions (including F()). I wonder if I missed anything. If not, why do we need parentheses around actual arguments?

Required to make path syntax work.

Thanks. By “path” did you mean module paths? I failed to see why module paths could make things ambiguous. Could you possibly provide an example or elaborate?

Because one can write

let a = A.F(M).B.b

Compared to

let a = A.F M.B.b (* data constructor F applied to b *)
let a = A.(F M).B.b (* invalid, .() is for index *)
2 Likes

Thanks, but OCaml (at least 4.11.1) does not seem to allow this anyways. The following code does not compile.

module M = struct end
module A =
struct
  module F (M : sig end) =
  struct
    module B =
    struct
      let b = ()
    end
  end
end

let a = A.F(M).B.b

Ah, yes, this use of application of functor in expression is not accepted by OCaml, but it is accepted by CamlP5, which in current 8.00 version A.F(M).B.b treats A.F(M).B as a valid longid, and in older version the AST isn’t the same but I believe it is still accepted. Although I doubt if there has been any preprocessing tools use this feature.


And probably also an important factor is that ML functor first appears in SML and incorporated into Caml lately, the syntax of functors in OCaml is a direct reflection of Modules for standard ML

It does work for types though

module M = struct end
module A =
struct
  module F (M : sig end) =
  struct
    module B =
    struct
      type b 
    end
  end
end

type a = A.F(M).B.b

And it is important that it works for types, because of applicative functors.

But is there a parsing ambiguity for types? Misleadingness aside, type a = A.F M.B.b seems unambiguous.