[ocaml-platform] An alternative proposal for namespaces
Leo White
lpw25 at cam.ac.uk
Wed Mar 20 11:03:49 GMT 2013
> 1. Getting rid of "simple namespace through filenames"
>
> I propose to keep search path files as the only way to define namespaces. For the typical user (who relies on
> ocamlfind), this does not change anything. The overhead for library developers is minimal. And this could drastically
> improve the quality of ocamldep. It would work as follow:
>
> - A namespace-qualified module name is looked up in search path files passed to ocamldep. For those references,
> ocamldep can produce a dependency to concrete files. This is the best of both worlds: (i) contrary to "ocamldep
> -modules", the build system does not need to recreate the lookup logic (in Leo's proposal, this even requires calling
> ocamldep many times in this process, which might be quite slow); (ii) contrary to "ocamldep" (without -modules), this
> work well even with files to be generated (and even when the source file is named differently).
>
> - An unqualified module name is resolved by taking local module declarations and "open namespace" statement into
> account. If the name can potentially refer to a namespaced module defined in on the search path files passed to
> ocamldep, ocamldep returns a dependency to concrete files as in the case above. Otherwise, it behaves as of today
> (returning either module names in "-modules" mode or concrete files otherwise, by looking at the file system). Since
> only non-namespaced module names are potentially returned as module names, the build system can behave as today (simply
> looking buildable files in -I directories).
>
>
> Also, "open namespace Foo" would fail if there is no definition of modules under namespace "Foo" in the search path
> files passed to the compiler. This is more robust than looking for foo-*.cmi files on the file system: these files
> might not exist yet, either because (i) dependency analysis is bogus or (ii) there is no actual dependency to any module
> in Foo in the current unit; or, on the contrary, there could be foo-*.cmi left from a previous compilation even though
> we have decided e.g. to change the name of the namespace. It's much better, in my opinion, to be able to work with a
> "closed world" assumption w.r.t. namespaces while compiling a single unit.
None of the above is helped by removing "simple namespaces through
filenames": it is all already supported by my proposal. If you don't
like some of the aspects of "simple namespaces through filenames" then
simply don't use them. You can always generate a search path file if you
are having strange dependency issues.
The majority of users do not require complex dependency analysis for
generated source files. I see no reason to prevent them from using a
convenient mechanism for defining namespaces. It is also the only
mechanism that is really in keeping with the current design of OCaml.
Search path files should only be necessary for unusual packages, not a
requirement for all packages.
> 2. Simplifying search path files
>
> I propose to get:
>
> (i) rid of aliases;
>
> (ii) define as an error the situation where the same namespace-qualified name is defined twice (with different target
> files) in the set of all search path files used together.
This should probably be a warning not an error. There is nothing wrong
with deliberately shadowing the description of a namespace.
> (ii) will strongly encourage libraries to avoid stepping on each other feet and thus make the life of the user better.
> Conflicts resolved by, say, a first-match policy are likely to fail at some point anyway (with bad error messages).
> Namespaces are introduced to avoid such problems.
>
> Complex namespace manipulation, which could benefit from aliases, are likely to be useful only to advanced users. I
> don't see it as a problem that they have to resolve aliases manually or with very simple tools.
I don't see how they can resolve aliases manually without knowing, on
the end user's machine, the location of all packages relative to the
location of their package. This also hard codes the aliases, what if the
other package moves?
> 4. Replacing "-name"
>
> Leo proposes to allow specifying the target compilation unit name (*.cmi/*.cmo/*.cmx/*.o) with a new compiler
> command-line argument.
>
> The use case is to simplify the life of library developers so that they don't need to use long names for all their
> source files. This should greatly simplify the migration of existing libraries to namespaces.
> In practice, however, most the source files in such a library will need to include a new "open namespace" directive to
> make other modules from the same library accessible. Also, we will need to inform the build system about the relation
> between source and target filenames. For ocamlbuild, for instance, this will probably mean the creation of a new kind
> of text file to describe this mapping.
The idea is that build systems like ocamlbuild do not *have* to support
the "-name" argument. It is there so that the build system *can* support
various naming conventions if it wants to. If we specify a particular
file format for specifying names then every build system *must*
recognise that format.
> - Lookup in mylib.mlpath for the compilation unit name corresponding to Mylib..Bar and use it as the target filename
> (if mylib.mlpath contains a line "Mylib..Bar:mylib_xxx", then the compiler will compile bar.mli to mylib_xxx.cmi). We
> hard-code in particular that in this mode, the source filename is equal to the module name as seen by "clients" of the
> library.
So either the user must write their own search path file specifying the
name of every single compilation unit, or the build system has to
generate it. If the build system has to generate it, how is that better
than using a direct argument?
More information about the Platform
mailing list