[ocaml-platform] An alternative proposal for namespaces

Alain Frisch alain.frisch at lexifi.com
Wed Mar 20 18:33:56 GMT 2013


On 03/20/2013 06:04 PM, Leo White wrote:
> The resolution of simple namespaces is much easier than the resolution
> of search path files. It is fundamentally the same resolution as OCaml
> uses now.
>
> If omake continues to use "ocamldep -modules" then it will have to
> implement the resolution strategy. To support *search path files* this
> will involve either parsing them itself or using the proposed "ocamlns
> ... -resolve Foo#Bar".

With my proposal, ocamldep -modules will emit two kinds of dependencies: 
file dependencies for namespaces modules (resolved by ocamldep itself, 
using search path files) and module dependencies (for non-namespaced 
modules), to be resolved by the build exactly as of today (only using -I 
directories, ignoring search path files).  Basically, we keep the legacy 
behavior (-I directories) for non-namespaced modules, and we provide a 
simpler API between ocamldep and the build system for namespaced modules 
(equivalent to "ocamldep" without -modules, but precise even in presence 
of generated source files or "renamed" units).  There will be no new 
resolution strategy to be implemented in, say, omake, just a trivial 
adaptation of the "ocamldep -module" postprocessing to accept file 
dependency directly.

> If it switches to using regular "ocamldep" with
> generated search path files then it won't need to implement the
> resolution strategy anyway.

Agreed, but this regular ocamldep does not work well with generated 
source files.  Moreover, it does at all with the proposed -name 
argument.  So I don't think that "regular ocamldep" will be an option.

> I'm not particularly worried about hypothetical build systems. If you
> want to implement such a build system then you should really add hooks
> into the OCaml compiler. This argument also assumes that catching
> "Sys.file_exists" is fine but catching "Sys.readdir" is impossible.

No, this argument does not assume that.  But catching Sys.readdir is 
useless, since you don't know which files the compiler is interested in. 
  The tool would have to assume that the dependency is on the entire 
directory, which is of course way too weak.

I've done an experiment with a build system based on capturing open/stat 
calls, and it worked really well, not only for ocaml, but also for C code.

>> I have the feeling to repeat myself...  I can understand that you consider these drawbacks as minor, but
>> do you agree they will apply even to users not using simple
>> namespaces?
>
> No, the only "problem" caused by simple namespaces is the lack of
> support for a hypothetical build system based on capturing file system
> accesses, and even this would work fine if you always used search path
> files.

Sorry, I maintain that my strategy will allow to have a better ocamldep 
which will result in simpler support in, say, omake and ocamlbuild.  I 
also maintain that people using simple namespaces could have weird 
behaviors of their build system (errors appearing or disappearing after 
a 'make clean') even though dependencies are "correct" (in fact, they 
are not, since the compiler would actually depend on the sheer presence 
of absence of some files).  And I maintain that a build system based on 
capturing file system accesses could be a viable strategy, and that this 
wouldn't work any more if the compiler starts to load whole directories.

> Not particularly, we are only talking about the lack of a warning
> telling you to change the name of a namespace that the file doesn't
> actually use.

Consider this piece of code:

  open namespace Foo
  module X = Bar

You decide to rename the namespace Foo in your project to Baz but you 
forget to update this file.  You still have a foo-bar.cmi in your 
directory, even though this file is now out of scope of your build 
system (it considers it as "source").  When you compile the wrong code 
above, the compiler does not complain, and the build system probably 
considers that foo-bar.cmi is a dependency of this code. Now you "make 
clean", and boom, the code does not compile any more.  (Or you commit 
your changes and other people from your update and get the same error.) 
  Or, even worse, you start changing some more code, and you get 
incomprehensible "Interface mismatch" because you still use the "dead" 
foo-bar.cmi.

If the namespace information is explicit described, such problems cannot 
appear.  In the example above, you will probably get a nice 
error/warning message on "open namespace", and at least an "unknown 
module" error on the reference to Bar (unless you have a local Bar unit, 
in which case you'll probably get a type error later, but still an 
unused "open namespace" warning).


Alain


More information about the Platform mailing list