Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Better module/namespace system #4679
Original bug ID: 4679
The module and/or file naming system for ocaml has some annoying restrictions that a modern language like ocaml shouldn't run it.
E.g. today I was trying to create a packed module, and one of the modules to be packed into it has the same name as a module in the standard library, so I had to add a useless prefix to make it work.
This is more silly considering that the module itself wouldn't actually be a top-level module, so there wouldn't be an actual naming conflict in the general case.
I would like to see a real namespace system in ocaml rather than a tonne of top-level module names with a high risk of naming conflicts, and having to make sure one always comes up with unique module/file names. The packing approach is cumbersome.
Comment author: @glondu
A suggestion (existing in Coq and Python) is to add the possibility to declare a directory as a module. For example, with the following tree:
adding the -R /a/b/c/root to the command-line tools would give access to Root.Toto, Root.Tata and Root.Foo.Blabla. A corresponding toplevel directive would also be needed.
This way, one could benefit from seemingly packed modules, without having to link them all. I guess this could be very useful (for example) for OCaml Batteries Included, and could give more structure to many projects, and simplify many build systems (even though ocamlbuild does already a lot in this area).
I am willing to think more on the details and contribute if this leads to an official adoption...
Comment author: @alainfrisch
The thing is that when you compile toto.mli and toto.ml, it is necessary to know that you are in the "namespace" Root, so this information should be given to the compiler (similar to the -for-pack option). But then, there is no need to rely on the structure of directories to extract the namespace information of .cmi files.
Here is another proposal: each compilation unit is defined as part of a namespace (a sequence of uppercase idents separated by dots). The namespace could be specified e.g. on the command line of the compiler or maybe in the source code itself. For instance, compiling a file foo.mli in a namespace A.B would produce a file foo.cmi that contains the namespace information A.B.
When the compiler needs to resolve a qualified name like A.B.Foo.t, it looks for a file a.cmi in the empty namespace, then for a file b.cmi in the namespace A, and finally for file foo.cmi in the namespace A.B.
The internal "persistent" identifiers and the low-level identifiers (for ocamlopt) should use the full names that include namespaces.
It should also be possible to "open" namespace. After a declaration like "open namespace A", a qualified name B.Foo.t would force the compiler to look for a b.cmi whose namespace is either empty or A, then for a file foo.cmi whose namespace is either B or A.B. The namespace for the current compilation unit could be opened by default.
Comment author: ertai
@Frisch "no need to rely on the structure of directories"
Directories are still useful for the compiler to find the modules we depend on.
Moreover using dots to separate namespace parts is "false good idea" in the presence of submodules. Simply because A.B becomes ambiguous, is B a submodule of A or is B a module
Comment author: jessicah
I don't see it being an issue. It would come down to how you order things (including the command line), which is the way ocaml behaves in a lot of things, such as two let bindings with the same name, or open A, B, and C, and each having a submodule with the same name.
At the very least, it's quite similar to trying to use -for-pack like my example where it failed because of two different foo.cmi files in different directories. Besides, the -for-pack/-pack feels like an ugly hack to workaround the limitation that a lack of namespaces (or whatever you'd like to call them) has initially created.
The current recommended practice for namespacing is to use module aliases as outlined here: http://ocamllabs.io/doc/namespaces-module-aliases.html .