New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compilation units as recursive modules #5480
Comments
Comment author: @hcarty This is an interesting proposal. What effect would this have on redefined values? For example: x.mli: x.ml: Which g is f using in your proposed case? Should one expect it to be the g exposed in the .mli or the g defined prior to f? Would "include X" be required at the top of x.ml to see types only defined in x.mli, or types/values defined later in the module? |
Comment author: @alainfrisch Scoping rules would be the same as for the "module rec" expansion. To refer to a definition further down in the module, you need to prefix with the module name explicitly. In your example, "f" uses the first "g". To use the second one, you would write |
Comment author: @hcarty Under 3.12.1: module rec X : sig X.(f A) raises an Undefined_recursive_module exception. Would this still be the case under your proposal if X is split into x.ml and x.mli? If t is not included fully in both the sig and struct sections then g fails with a compilation error. Would this duplication requirement change under your proposal? |
Comment author: @gasche Note that you can remove the exception by eta-expanding f: let f x = X.g x The idea is that, under a backpatching semantics, "let f = X.g" would force X at definition time, which results in an undefined function |
Comment author: @alainfrisch It could be useful to improve the compilation strategy for recursive modules so as to cover more cases, but this is rather independent from the proposal. Concerning the duplication of type declarations: currently, recursive modules makes it possible to avoid duplication of structural type elements. For instance, your example with polymorphic variants. Or the following: module rec X : sig One could also consider adding a "type-include" mechanism, that would allow to write: module rec X : sig |
Comment author: @lefessan I submitted a patch a while ago to improve the compilation strategy for recursive modules (#5286). Without this patch, I think a lot of programs would not compile if all units were recursive by default. Have you tried to compile some non-trivial applications with this patch ? |
Comment author: @alainfrisch Fabrice, unfortunately, I haven't tried your patch. At LexiFi, we have used a simpler form of the proposal for some time; in our version, compilation units are type-checked as recursive modules (which allows nice type-level forward references and references from the implementation to the interface) but compiled as usual (compile-time error if we use module recursion to refer to a dynamic component). |
Comment author: @xavierleroy I know for a fact that recursive modules in OCaml are a bit of a hack, in that the typechecking is incomplete and the compilation can fail at run-time in rather mysterious ways. That's tolerable as long as recursive modules are clearly marked as an experimental language extension. But I'm extremely wary of putting them at the heart of OCaml, so to speak, namely in the processing of compilation units. That's just calling for major trouble. |
Comment author: @mshinwell @Frisch Are you happy to close this given Xavier's response, or not? |
Comment author: @alainfrisch Ok, closing. |
Original bug ID: 5480
Reporter: @alainfrisch
Status: closed (set by @alainfrisch on 2016-12-12T16:53:51Z)
Resolution: won't fix
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)
Monitored by: @gasche @protz mehdi @diremy
Bug description
A compilation unit X with an implementation x.ml and an interface x.mli is morally interpreted as the following declaration:
module X : sig
[content of x.mli]
end = struct
[content of x.ml]
end
What about interpreting it instead as a recursive module declaration:
module rec X : sig
[content of x.mli]
end = struct
[content of x.ml]
end
This would make it possible to refer, in x.ml, to components defined further down in the same file and even to structural types (and class types, module types) defined in x.mli to avoid code duplication.
The text was updated successfully, but these errors were encountered: