[ocaml-platform] on the need and design of OCaml namespaces
Leo White
lpw25 at cam.ac.uk
Wed Feb 27 14:16:41 GMT 2013
>I want to see concrete examples!
It is difficult to provide examples of people doing something that is not
currently supported. Using the compiler itself as source of possible module
names, I see the following module names that I could easily picture
multiple libraries using:
Warnings, Tbl, Misc, Config, Errors, Env, Types,
Protocol, Shell, Common, Table, Log, Options
>Maybe you want to use both String.Set and Int.Set, but
>you're not going to "open" String and Int anyway.
I can easily imagine libraries that provide there own specialised set
implementation as Foo.Set. I can also easily imagine that the kind of
program that requires specialised sets for one kind of data would also
require specialised sets for another kind of data.
>use Xmllight.parse and Xmlm.parse (although it is not clear that this
>will happen in the same module), but you're not going to open Xmllight
>or Xmlm globally in your unit.
But I might open Xmlm and Json (an imaginary json parsing library) in the
same unit.
>
>> I also think that open statements (even at the top of a file) are a very
>> good thing.
>
>If put at the top of the file, I don't see them as fundamentally
>different from command-line arguments, and the meaning of the short name
>is decided by the order of open statements, which is also quite fragile.
Except that open is written by a programmer, whilst command line arguments
are often written by a tool/build system.
>And "open statements" (for modules, not even namespaces) are generally
>considered as a dangerous feature, because they are the source of
>technical problems (dependency analysis), because they make the code
>harder to read and refactorize, and because it makes modules more
>fragile (if a module B is extended with more components, they can hide
>components with the same name from another module A which is open before
>B in some client code). Making "opens" more local is a way to reduce
>those problems. I'm thus surprised by your claim that open statements
>are very good thing.
They are a good thing in comparison to command-line arguments. It is
obviously better if people open things locally, or use the full name
explicitly (although this can clutter the code and reduce readability).
>> They show which libraries the file is going to use.
>
>This seems to confirm that what you're aiming at is really a way to
>specify in the source code which libraries are used. But then we should
>push the reasoning further and ensure this specification is the only one
>required to use a library. Why should we accept to pass -I / -pp / -ppx
>flags to the compiler (and specify again libraries at link time) when
>the information is already part of the source code?
I'm certainly not against support for inferring command-line arguments from
the contents of files, but I do think that they are separate issues.
The "open Foo" is part of the semantics of the program, it has meaning
regardless of the environment it is being compiled in. Command-line
arguments are about providing an interface between the program's semantics
and its surrounding environment (e.g. the filesystem).
There is also a reasonable argument that inferring the compiler arguments
is the job of tools like ocamldep and the build system, rather than the
compiler.
>> Currently, a file using a library that does not use pack will simply
>> launch straight into using modules with short names that give no
>> indication of their origin.
>
>Many of the third-party libraries I use export a single module, which I
>never "open", and whose name is unique enough to avoid clashes (e.g.
>Postgresql, Sqlite3, Xmlm). Some libraries use prefixes (Nethtml, with
>an internal Nethtml_scanner module; Lwt comes with Lwt_util,
>Lwt_condition, Lwt_mutex, etc). It would have been crazy, indeed, for
>Nethtml to have an internal "Scanner" module, or for Lwt to expose a
>"Mutex" module. I'm fine with this situation, but I can understand that
>in some cases, it would make sense, for instance, to alias Lwt_mutex to
>Mutex in a given project.
More than just make sense, it would actively improve the readability of
code using modules like Lwt_mutex.
>So I don't agree with the opinion that -pack is currently the only way
>to avoid clashes! It would be useful to get some statistics about the
>use of -pack in OPAM.
I think that it is a little dangerous to judge how much people would use a
proposal based on how many people used its complicated and deeply flawed
predecessor.
> > I must look in the build system to find out
>> what they refer to. By encouraging people to use namespaces, these files
>> will instead start with "open namespace Foo", and it will be obvious
>> what libraries they are using.
>
>So if you have a program like:
>
> open namespace Foo
> open namespace Bar
>
> (* ... several hundreds of lines ... *)
>
> .... Baz.parse ...
>
>then, yes, you know that this program uses the Foo and Bar
>libraries/namespaces, but you have no idea where Baz comes from. This
>is fine, as long as you don't have clashes of "short" names, i.e. Foo
>and Bar are different enough to not provide top-level components of the
>same name.
I certainly agree that it is bad practise to rely on shadowing, it would be
better to open the modules more locally when they have clashes. This is why
we should provide a way to open namespaces locally. I also think that the
"open"s at the top of the file are a definite improvement on command-line
arguments.
>> OCamlDep would simply treat any namespace for which it could find
>> no ".ns" file as an implicit namespace.
>
>I have to admit that I'm a little bit lost and I don't really know which
>"namespace proposal" we are talking about (mine has only ".ns" file, no
>other notion of namespaces).
The parts of my post that referred to ocamldep were in response to your
commments about my addition to your proposal (I think I see how you got
lost). In other words, they were about adding support for having files like
"core-mutex.mli" which would automatically be placed in a Core namespace.
The idea (which I will call implicit namespaces) is that, for convenience,
you would not need to provide a ".ns" file for these files.
I think that it could cover a majority of the uses of namespaces, while
still allowing explicit ".ns" files for more complex namespaces and to make
life easier for build systems. I particularly like how simple this would be
to explain to a beginner.
More information about the Platform
mailing list