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 *)
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.