Has there been a syntax proposed for combining .mli into .ml?

I had a thought coming at this problem from the opposite direction from that suggested by @gasche.

We have a nice and concise syntax for fully opaque types in

type t

and for “private” types (destructable but not constructable) in

type t = private foo

So I’ve been wondering if we could smooth out this rough edge with similar syntax to mark transparent types. E.g.,

type t = transparent
(* or *)
type t = public
(* or *)
type t = _
(* or whatever *)

Which would mean something like, type t (in a signature) exposes exactly whatever the type is specified to be (in the implementation). This would mean you don’t have to repeat the type definition in the interface, but just note that the type should be exposed transparently, i.e., mark it as public.

IMO, this feels a bit more natural (and less complex) than a feature that would allow “importing” parts of an interface file into the implementation. I think the key point in its favor is that it allows us to continue thinking of interfaces exclusively as a way of presenting what is to be exposed by an implementation.

Two problem I can anticipate with this idea: (1) afaik, the type language is currently identical in signatures and structures, and this would break that symmetry (but of course there are already many asymmetries between the two); (2) more significantly, imo adding features which only work in mli files but not on signatures generally seems like a troublesome complexification, but I don’t know what my suggestion here would imply when used in a signature that could be implemented by many different modules… iiuc, the idea of importing types from an mli file also has this problem?

[edit] a third problem, which is the worst of the tree I think, is that under my suggestion interfaces would no longer give you everything needed to know the public api of an implementation. Gache’s suggestion doesn’t have this problem.

2 Likes