In this post, I'll try to take a high-level view of the discussion that has happened so far. You can take this as an (opinionated) summary.<br><br>The main ideas of my proposal linked at the top, or more generally my work on what people have been suggesting for namespaces, are the following:<br>
<br>1. Namespaces are about the out-of-the-language-question of how a given in-source compilation unit name (masquerading as a module name) maps to an in-filesystem compilation unit.<br>2. I was suggesting new features that (mostly) do not change the OCaml language itself, but the semantics of this mapping and the way it is given to the type-checker. This is a choice that some people may not agree with (more on that later).<br>
3. Actual OCaml implementations also have a notion of "internal module name" that is contained in compiled object files; two modules of the same internal name cannot be mixed together. This has important practical implication, and we can consider the implementation space for internal module names.<br>
<br>Alain has a large codebase with house-developed tools, unique build process conventions, and the ironically unusual constraint of compiling quickly on Windows. He pushes for having as few changes as possible. No change to the internal module names (this means developers should use long hopefully-unique filename to avoid conflicts), no change to the structure of compilation unit names (no hierarchy), and a simple compunit-name-to-compunit-name mapping to alleviate the pains. In my initial proposal, this corresponds to restricting the compilation environment descriptions to a flat mapping built by literals and merging only.<br>
<br>Leo has the fairly different use case of Janestreet Core's library in mind: hierarchy is important (Core.Foo looks better than Core_Foo and "open namespace Core" is important), changing the language for greater good is ok, and his particular suggestion is an in-language, compunit-wide "in Core.Foo" construct that would both be added to the internal module name, and be used to generate the mapping from compunit names from compunit *on the developer side*, rather than on the user side (with then the simple semantics that all mappings from the search path are merged). This can against be seen as a way to define the compilation environment, giving slightly more control to the module provider (mostly a placement in a hierarchy). It corresponds to a restriction of the way to define compilation environments that is even more severe, the user having no control (compilation environments are built as the merging of all developer-generated environments present in the search path).<br>
<br>Daniel is opposed to the addition of a new "namespace" concept to the OCaml language. It is not completely clear to me whether he objects to:<br>1. the addition of more flexibility in the way compilation unit names are mapped to compilation units, outside the language (the mapping file Alain suggests, the more expressive mapping languages I have considered, or a compilation-option version of the "in Foo.Bar" proposed by Leo)<br>
2. or only the addition of a new concept *in the language itself*, such as can be seen if we insist to write Core#Std#Map.Make rather than Core.Std.Map.Make<br><br>I lament that, expect Alain, nobody gives a damn about letting users redefine their own names or paths in a different way that what the module provider planned for. I think it's an important part of the design space that may allow quite convenient things (eg. scenarios of companies maintaining a in-house repository of modules with pinned version, and still being to interact with non-curated module collections in the same programs), but apparently this is not something people care about. Well, that's how it is, and hopefully this won't turn out to be overly restrictive in the mid-term future.<br>
<br><br>## A more detailed discussion of Daniel's arguments<br><br>Daniel, I am glad that you defend this point of view, as I myself grow more and more conservative of language extension ideas (maybe it's a contagious effect of vicinity to OCaml designers...). I do completely agree that new language features should be motivated by a (expressivity vs. complexity / kludgeness) estimation, and that it is not a priori clear that we need another "programming in the large" concept above modules.<br>
<br>Regarding point (2): About a year ago, I have worked with Nicolas Pouillard on a way to make the objection go away, by seeing compilation unit names only as modules in the source code: given a hierarchical compilation environment, there is a principled way to turn any non-leaf path (that does not denote a compilation unit by itself) into a module. Instead of Core#Std#Map, we could write Core#Std.Map (seeing Core#Std as a module) or even Core.Std.Map (seeing Core as module) without changing the semantics of my proposal (or any consensual restriction of it). You can find this specified in an older design document,<br>
<a href="http://gallium.inria.fr/~scherer/namespaces/pack_et_functor_pack.html">http://gallium.inria.fr/~scherer/namespaces/pack_et_functor_pack.html</a><br>I had decided not to link it in my introductory mail because it add a bit more complexity to the semantics of mapping compilation unit names to compilation units, and my feeling was that discussing the design space of a simpler basis was a better way to start a discussion that would certainly become unwieldy to the risk of being improductive.<br>
<br>Summing things up: if you have a hierarchical mapping outside the language, you can make it appear in OCaml source code as just as module hierarchy, as you suggest. I think it actually adds *complexity* to the underlying design, so there is a price to pay to hide this distinct notion of (structured) compilation unit name. I would be ready to pay that price if there is a wide agreement it is the right thing to do, but I personally favor more explicit designs, at least as an experimentation and discussion device (I think we should make the difference explicit and have a (module Core#Std) construct turning a non-leaf compilation unit path into a module with submodules, with the shared understanding that we can decide to hide it under a syntactic ambiguity).<br>
<br>(The documentation also discusses the possibility of having *functors* that span several compilation units, and that is something Yaron has requested in the past. It is more complex and I don't think it is as ready, robust and canonical as the module part, so I encourage you to ignore it in the context of this discussion.)<br>
<br>Regarding point (1), your suggestion to use .cma as an already-existing grouping of modules in submodules that could help solve module name conflicts, I feel this is a more anecdotal part of your (still imprecise) proposal that is more in the "you see it doesn't need to be that complex" league that an actual principled design. I have a sympathy for the "least effort" design process that it shares with Alain's proposal, but I think it should not stop us from thinking about the whole design space in a scientific way. (For example: unless I'm mistaken, .cma cannot currently embed .cma, so your proposal for implementation reasons cannot expression non-flat module hierarchies.) There are important technical details left to be defined, such as how to avoid internal name clashes between submodules of different .cma-packs. My intuition is that getting the details straightened out would amount to re-implementing -pack (in particular the -for-pack approach to internal module names prefixing) in terms of .cma rather than .cmo. So the mapping from compilation unit names to compilation units would still be entirely directed by the filesystem and search path as it currently is, but with link-economic module packs. Why not, that's an idea we could explore in more details, but note that its semantics would still be split in two different "phases":<br>
- a new notion of structured paths Foo#Bar that allows to denote a compilation unit for bar.cmo embedded into foo.cma<br>- a possible way to hide this additional structure to source code, masquerading Foo as a module, with a precise semantics when it is used for something else than a projection (as in the document linked above; in fact you could reuse the same proposal, I think)<br>
<br>This particular implementation choice gives away on quite a few things we might want to have, such as:<br>- the ability to merge two sets of submodules that share a common parent name (admittedly this is not useful in a provenance-oriented view of compilation unit naming, but more in a Data.List view that is not necessarily the good one to start with)<br>
- the ability for users to build new/distinct parallel module organizations<br>- more-than-depth-2 hierarchies (implementation detail; might be fixed with non-neglectible amount of work)<br>- compilation unit name aliasing / redefinition<br>
<br>But it looks interesting. Please go ahead with more detailed proposals!<br><br><div class="gmail_quote">On Mon, Feb 25, 2013 at 3:15 PM, Anil Madhavapeddy <span dir="ltr"><<a href="mailto:anil@recoil.org" target="_blank">anil@recoil.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On 24 Feb 2013, at 19:26, Christophe TROESTLER <<a href="mailto:Christophe.Troestler@umons.ac.be" target="_blank">Christophe.Troestler@umons.ac.be</a>> wrote:<br>
<br>
> On Fri, 22 Feb 2013 11:41:10 +0000, Anil Madhavapeddy wrote:<br>
>><br>
>> There's one scenario which absolutely requires the ability to explicitly open a particular namespace: camlp4 code generation.<br>
>><br>
>> Right now, several camlp4 extensions break because they use modules from the standard Pervasives library, and have no way to explicitly state that. If Core.Std is opened, then compilation fails.<br>
>><br>
>> The two workarounds are:<br>
>> - hack the build system to pass -pp options to the camlp4 generator. Painful.<br>
>> - have some facility to explicitly open 'Caml_std' or 'Core_std' locally, irrespective of the current module environment.<br>
>><br>
>> I believe namespaces addresses the latter workaround.<br>
><br>
> Camlp4 can insert some code to alias the standard modules needed by code generation at the beginning of the source files (not foolproof because a name needs to be generated but good enough in practice). It would be better if that facility was provided by a Camlp4 module instead of needing to be redone by each extension.<br>
<br>
</div>That's an interesting idea. The only hitch is that it's a little hard to do in one pass, as the code generation is called on the local AST fragment.<br>
<br>
I think it would work if placed as a feature into type_conv itself, as the individual generators (e.g. sexp/orm) all register themselves with it quite early. They could request global modules, which type_conv does in one pass (thus also avoiding duplicate requests for the original namespace).<br>
<br>
CCing Markus Mottl to see what he thinks...<br>
<span><font color="#888888"><br>
-anil<br>
</font></span><div><div><br>
_______________________________________________<br>
Platform mailing list<br>
<a href="mailto:Platform@lists.ocaml.org" target="_blank">Platform@lists.ocaml.org</a><br>
<a href="http://lists.ocaml.org/listinfo/platform" target="_blank">http://lists.ocaml.org/listinfo/platform</a><br>
</div></div></blockquote></div><br>