viewgit/inc/functions.php:78 Function create_function() is deprecated [8192]

first version of the synthesis

Author Gabriel Scherer <gabriel dot scherer at inria dot fr>
Author date 2012-01-02 16:50:53
Author local date 2012-01-02 17:50:53 +0100
Committer Gabriel Scherer <gabriel dot scherer at inria dot fr>
Committer date 2012-01-02 17:06:28
Committer local date 2012-01-02 18:06:28 +0100
Commit 30ff408904207ab7fadea0b1edb0abaac322a6f3
Tree ea15a29a5d0e817f819ff8e922c384498018efd0
Parent 4586122dfed77b6b597d21f9e7c1b86242fdcb37
first version of the synthesis
Affected files:
alain.text : file, diff
fabrice.text : file, diff
martin.text : file, diff
namespaces.text : file, diff
nicolas.text : file, diff
related.text : file, diff
diff --git a/alain.text b/alain.text
new file mode 100644
index 0000000..99b914e
--- /dev/null
+++ b/alain.text
@@ -0,0 +1,159 @@
+A proposal by Alain Frisch:
+
+> Here is my current proposal (not including Jacques' suggestion to
+> allow using internal names as file names locally):
+>
+>
+> Main ideas and goals
+> --------------------
+>
+> * Primary goal: Allow several libraries (maybe parts of the same
+>   build tree) to expose modules with the same name from the point of
+>   view of client code.
+>
+> * Main idea: Add an intermediate layer of indirection (called
+>   "namespace maps" or "namespaces") between (1) module names that
+>   refer to compilation units, used in source code and (2) concrete
+>   files.
+>
+> * Secondary goals:
+>
+>
+> ** Keep the burden on external tools as small as possible, and try
+>    to maintain existing properties of the system, in order to ensure a
+>    smooth transition path for users and tools.
+>
+> ** Never force a user to use the new features.
+>
+>
+> Namespace map files
+> -------------------
+>
+> A namespace map file foo.cmn is a sequence of lines of the form:
+>
+>  ModuleName: filename
+>    where ModuleName is an uppercase identifier (which defines how a
+>    module is to referenced from a source file) and filename is a
+>    lowercase or uppercase identifier (the real module
+>    name). Typically, filename would include a prefix to identify its
+>    library.
+>
+> (Empty lines and lines starting with a #-character are ignored, etc.)
+>
+> Conceptually, a line as above tells the compiler that resolving
+> ModuleName as a toplevel module name should be done by looking for
+> filename.cmi in the filesystem.
+>
+> It is an error if a given .cmn file contains two bindings for the same ModuleName.
+>
+> Bindings in .cmn files are not transitive. They map module names
+> used in source files directly into file names.
+>
+> A .cmn file can also be seen as a way to obtain internal ModuleNames from filenames (reverse mapping).
+>
+>
+> Extensions to the source language
+> ---------------------------------
+>
+> Syntactically, a namespace is an uppercase identifiers.
+>
+>   open namespace Foo  (* in structures and signatures *)
+>
+>   let open namespace Foo in expr (* in expressions *)
+>
+>   Foo..ModuleName  (* head of module paths *)
+>
+>
+>
+> Behavior of the compiler
+> ------------------------
+>
+> To interpret a namespace Foo, the compiler looks for a file called
+> foo.cmn (or Foo.cmn) in the load path (the first matching file is
+> used).
+>
+> Foo..ModuleName is interpreted by looking for a mapping
+> "ModuleName: filename" in foo.cmn, and the resolution continues
+> with Filename (without using namespace maps), i.e. the compiler
+> looks for a file filename.cmi on the load path. "Filename" is
+> called the external module name corresponding to the local
+> reference ModuleName.
+>
+> The two other constructions bring all the bindings from the .cmn
+> file into a mapping maintained by the typing environment. This
+> mapping is used to resolve a toplevel module name not explicitly
+> qualified with a namespace.
+>
+> The internal representation (dumped in .cmi files, and later in
+> binary dumps of typedtrees) contain the external module name for
+> toplevel module references.  (It could also keep track of the
+> internal name used in the source file, but interpreting such a name
+> depend on the context, so it might be better if tools which process
+> .cmi/binannot files do a reverse mapping themselves, based on
+> explicit user decisions.)
+>
+>
+> The .annot files produced by the compiler contain external module
+> names (which correspond directly to filenames). It is the
+> responsibility of tools which consume .annot files to read .cnm
+> files (passed to them explicitly) and apply the reverse mapping if
+> one wants these tools to produce reports with internal names.
+>
+>
+>
+> Behavior of ocamldep
+> --------------------
+>
+> A new mode "ocamldep -namespaces" returns the list of namespaces
+> found in the source file (same spirit as "ocamldep -modules",
+> i.e. in this mode, ocamldep does not resolve namespace references to
+> concrete .cmn files).
+>
+> In normal "Makefile" mode, ocamldep reads the .cmn files as the
+> compiler would do (and fails if it cannot find a .cmn file), and
+> apply them to resolve toplevel module names (or what it believe
+> are/might be toplevel module names). The external module names are
+> then translated to files with path (as today).
+>
+> "ocamldep -modules" is similar, but it outputs external module names
+> (after the mapping described in .cmd files) directly.
+>
+> Something to be noted is that "ocamldep -modules" now reads other
+> files than the source file on which it is applied (only if the new
+> language features are used; and it doesn't need to read or look for
+> the existence of other files than .cmn files).
+>
+>
+> Impact on build systems
+> -----------------------
+>
+> Makefiles should not require any significant change. Dependency
+> scanning is triggered manually, so it is not really necessary to
+> maintain exact dependencies on .cmn files.
+>
+> OMakefile rules could be slightly adapted to know about dependencies
+> on .cmn files and force these files to be refreshed
+> (generated/preprocessed/copied around) before calling
+> "ocamldep -modules".  That said, people could probably live some
+> time without this change, if they use only static .cmn files or
+> empty the dependency cache manually when these files change.
+>
+> ocamlbuild: I'm not familiar enough with this system to comment
+> seriously on it. I assume it needs to know about all the
+> dependencies in order to decide what to copy in the dedicated build
+> directory, and "ocamldep -namespaces" should be useful for it.
+>
+>
+>
+> Behavior of ocamldoc
+> --------------------
+>
+> By default, ocamldoc would produce documentation with external module
+> names all over the place.  It is extended to accept .cmn files on its
+> command-line. These files are used as a reverse mapping from external
+> names to internal names. (In case when several internal names exist
+> for the same external name, one can specify for instance that the
+> first instance is used.)  The exact way how internal/external names
+> are used in the output of ocamldoc is to be decided by the backend.
+> (For instance, an HTML backend could show the internal name, with the
+> external name displayed in a tooltip when hovering the reference.)
diff --git a/fabrice.text b/fabrice.text
new file mode 100644
index 0000000..c79f5c6
--- /dev/null
+++ b/fabrice.text
@@ -0,0 +1,209 @@
+A proposal by Fabrice Le Fessant:
+
+> Here is the proposal for namespaces that I recently wrote. It is
+> already partially implemented in an SVN branch, but there is still
+> work to do. OCamlpro already has a partial funding for what remains
+> to be done (see at the end), so, if you are interested in seeing
+> this work finished, you might want to consider co-funding it to
+> speed things up.
+>
+> --Fabrice
+>
+> Proposal for OCaml Namespaces
+> =============================
+>
+> A namespace is a path that is added in front of a toplevel module name
+> (compilation unit) to remove ambiguities between toplevel modules.
+>
+> Rationale
+> ---------
+>
+>   Namespaces can be used to link different modules with the same
+> module name from different libraries in the same executable.
+>
+> Namespaces and modules
+> ----------------------
+>
+>   Namespaces use the same notations as modules: a namespace is
+> composed of capitalized identifiers ([A-Z][a-zA-z0-9_]*) separated by
+> dots. This notation allows to switch easily between namespaces and
+> modules.
+>
+>   A module can be qualified by a namespace by prefixing the module
+> name by the namespace name and a dot. QM = NS.M
+>
+> Adding a module to a namespace
+> ------------------------------
+>
+>   The namespace of a module is specified with the "-ns NS" argument to
+> the compiler.
+>
+>   It could also be specified by a special notation at the beginning of
+> the file. For example:
+>
+> "in namespace NS"
+>
+> or better:
+>
+> "in module NS.M"
+>
+>   (I would personally vote against, as it would prevent including the
+> source of the module in another module, such as "ocp-pack" does for
+> sources. But if we go for it, I would prefer the second one, that
+> specifies both the namespace name and the toplevel module name. The
+> compiler would then check that the current source is either "M.ml" or
+> "M.mli". However, it is yet unclear, but a construct might simplify a
+> lot the work of ocamldep with namespaces.)
+>
+>   The module can then be referenced from other modules using the fully
+> qualified name "NS.M". It cannot be referenced using only "M", even if
+> its interface file can be found directly in the load path (except in
+> "compatibility mode").
+>
+> Compatibility mode
+> ------------------
+>
+>   When neither the option -ns, nor the construction "in
+> namespace/module" are specified, the compiler does not care about
+> namespaces (it is in "compatibility mode"). When a module name is
+> specified, it chooses the first matching toplevel module name, without
+> taking the namespace specification (if one is available in the object
+> file) into account.  However, it will save the dependency towards the
+> fully qualified module in the object file (i.e. including the
+> namespace name), so that linking will still take namespaces into
+> account. This mode should allow libraries developed before namespaces
+> to compile with no problem with the new version.
+>
+> Namespaces and modules
+> ----------------------
+>
+>   Namespaces cannot be used instead of modules. The only construct
+> where they can be used instead of modules is "open NS" (and of course
+> "let open NS in"). They cannot be used instead of M in the following
+> constructs  "include M", "Make(M)", "module N = M".
+>
+> Module Aliasing
+> ---------------
+>
+>   Since namespaces cannot be used in "module N = M" to change their
+> name locally, we propose to introduce a new construct "open NS as NS2"
+> (and "let open NS as NS2 in ...") to alias them locally. The same
+> construct would be useful for modules too, to alias them without
+> importing them (and thus forcing a link even when just a type would be
+> useful), as the "module N = M" would.
+>
+> Name priority
+> -------------
+>
+>   If both a module and a namespace share the same name, the module
+> always hides the namespace. If two modules have the same qualified
+> name, the first in the load path hides the other ones.
+>
+> Values in namespaces
+> --------------------
+>
+>   It is sometimes useful to have values, types and exceptions directly
+> available in a namespace. For that, any value in any module in any
+> namespace "NS.Pervasives" is automatically available when namespace
+> "NS" is referenced. If two values have the same name, the first one in
+> the path hides the other ones; if they are available in the same
+> directory in the load path, the value in the first module in
+> alphabetical order hides the other ones.
+>
+> Namespaces and directories
+> --------------------------
+>
+>   Until now, there is no way for the compiler to guess the namespace
+> of an object file without opening the file. This means that, when
+> compiling a module using namespaces, the compiler would need to open
+> all existing object files to discover which namespaces they are
+> included in. For example, if a module uses "open X", and no "x.cmi" is
+> available in the path, the only way to know if X is a namespace is by
+> opening all interface files to check if one of them is in namespace
+> X. This would be very expensive to do and would probably compromise
+> the automatic computation of dependencies too.
+>
+>   Thus, we propose different mechanisms to tell the compiler which
+> namespaces are available without loading all the interface object
+> files:
+>
+> - Any sub-directory in a path might be the name of a namespace, and
+> object files in that sub-directory are modules in the namespace (and
+> sub-directories are sub-namespaces); Note that the same directory
+> might appear in different directories of the load path, so that all
+> the included modules will appear to belong to the same namespace;
+>
+> - In any directory, all files must belong to the same namespace.
+> A special file "ocaml.ns" can be used to specify that namespace
+> (text file, containing the namespace on the first line).
+>
+> "ocaml.ns" can also be used when compiling a file, to discover which
+> namespace it is in, if no "-ns NS", or "in namespace NS" is provided (if
+> they are provided, the compiler should check they share the same
+> value).
+>
+> Compatibility of build systems
+> ------------------------------
+>
+> "ocamldep" should be easy to adapt to namespaces when printing makefiles
+> dependencies. Build systems using the -modules option of ocamldep will
+> need to be modified to handle namespaces correctly. It is the case of
+> "ocamlbuild", "omake" and "ocp-build" (our own build tool). The main
+> challenge is probably "omake", as it is not supported anymore by anybody
+> so we would need to decide if it is worth adapting it or not.
+>
+> Current Implementation
+> ----------------------
+>
+>  There is already a partial implementation of this proposal in the SVN.
+> What is NOT yet done:
+> - the "in namespace NS" construct (only the -ns NS option is implemented)
+> - values in namespaces (Pervasives sub-namespace)
+> - support for "ocaml.ns" files
+> - changes to "ocamldep" and "ocamlbuild"
+> - testing, a lot of testing !
+
+
+
+> Here is a proposal to extend my former proposal to fix ocamldep
+> problems, using ideas from Scala:
+>
+> Every source file using namespaces should begin with:
+>
+> in namespace NS0
+> with import
+>        NS1
+> and NS2._
+> and NS3.{ _ }
+> and NS4.{A;B;C}
+> and NS5.{A->B; B->_; _}
+> and NS6.{X;Y;Z} as NS7
+> ;;
+>
+> The new construct tells that:
+> - the current module is in NS0
+> - it uses some modules of NS1 (not specified which ones)
+> - it uses some modules of NS2 (not specified which ones)
+> - it uses some modules of NS3 (not specified which ones)
+> - it uses modules A, B and C of namespace NS4
+> - of NS5, it uses module A, but locally renamed as B, it does not use
+> the original B module, and uses all the other modules
+> - it uses modules X, Y and Z of NS6, and locally defines a namespace
+> NS7 composed of the values included in these 3 modules (this replaces
+> the Pervasives sub-namespace mechanism, and allows to specified
+> exactly the order of modules if necessary).
+>
+> "ocamldep" can use this construct to exactly know which namespaces are
+> available in the module, and which modules of these namespaces are
+> used. If the modules are not specified, as for NS1, NS2 and NS3 in the
+> preceeding example, it might infer false dependencies, but such
+> dependencies can be removed by manually removing them from the
+> namespaces (using the NS.{ X -> _ } construct to remove module X from
+> NS).
+>
+> Once this construct as been put at the beginning of the source,
+> namespaces are used just as modules (you still need to use "open NS"
+> even if you used "import NS", just as in Java/Scala).
+>
+> I think this would completely fix the problem of dependencies, and
+> provide powerful hierarchical and extensible namespaces.
diff --git a/martin.text b/martin.text
new file mode 100644
index 0000000..c213806
--- /dev/null
+++ b/martin.text
@@ -0,0 +1,30 @@
+A proposal by Martin Jambon:
+
+> A namespace name follows the same syntax as a module name (Abc.Def).
+> There are no changes to the OCaml syntax, namespaces being used like
+> modules where possible.
+>
+> A list of compilation units forms a package. A package is defined by a
+> "Package" file that contains:
+> - the name of the package (default: current directory name)
+> - the containing namespace (default: empty path)
+> - the list of compilation units
+> - the packages used by this package (default: none)
+>
+> Several packages may use the same namespace as long as their
+> compilation units have different names.
+>
+> Sample Package file:
+>
+>  name = atdgen
+>  namespace = Mylife.Atdgen
+>  provides = Error Oj_run Ob_run
+>  requires = biniou yojson atd
+>
+> Package files are found by looking for */Package in the package search
+> path similarly to how ocamlfind finds META files. The presence of a
+> Package file overrides the search of cmi files using the legacy "-I".
+>
+> We believe that this proposal allows the compilers, ocamldep, ocamldoc
+> and ocamlfind to be adapted to support the new features and are
+> backward-compatible.
diff --git a/namespaces.text b/namespaces.text
new file mode 100644
index 0000000..bc912c0
--- /dev/null
+++ b/namespaces.text
@@ -0,0 +1,529 @@
+The various namespace proposals for OCaml: a summary
+
+There has been a lot of different proposals during the recent
+discussion of 'namespaces' for OCaml. I have listed, in no particular
+order, one proposal by Martin Jambon, one by Fabrice Le Fessant, one
+by Alain Frisch, and one by Nicolas Pouillard.
+
+All proposals being rather complete and precise, but using slightly
+different concepts and vocabulary, it is difficult to compare them and
+know which part are essential and which are less-important to
+evaluate.
+
+In the present document, I try to present those four proposals in
+a unified manner, to make comparison between them easier. This is not
+meant to be a piece of opinion, there is no judgment of whether the
+differences exposed are good or bad. I may still have misunderstood
+some of the proposal aspects, so feel free to correct me if necessary.
+
+The discussed proposals are included, for reference, at the end of the
+document. If only to convince you that my "synthesis" is *not* longer
+than the four proposals concatenated!
+
+The document is split in three part:
+
+1. A precise (formal?) framework to think about how the current
+  semantics (and eventually the various proposals) relate module
+  references in the OCaml source code to compilation units in the
+  filesystem. I came to this frame by comparing and trying to
+  synthetise the various proposals, and this is the novel aspect the
+  document.
+
+2. A description of how, to my understanding, the current propositions
+   fit in this framework. I'm not trying to completely sum up or
+   rewrite the proposals, but to describe in an unified manner
+   a specific aspect of them (the module reference -> compilation unit
+   relation) that I think is crucial. Of course, I may have
+   misunderstood some aspects of the proposal (feel free to correct me
+   and make suggestions), and the framework does not encompass all
+   aspects of all the proposals.
+
+3. Some discussion of how we should evaluate the proposals and which
+   aspects have not been considered in the unified presentation. While
+   parts (1) and (2) aim at absolute objectivity, this one is more
+   subjective and is warmly open to further discussion.
+
+
+PS: I'm considering putting the synthesis on a wiki somewhere, to be
+able to evolve the document according to your remarks, and even allow
+you to contribute directly if you wish. I'm not sure where to host it;
+in particular, it would probably be best if it was non-discoverable,
+not to disturb the current semi-private nature of the discussion. Any
+suggestions appreciated.
+
+# Part 1: A precise description of the way module names in OCaml
+  source relate to external compilation units
+
+## Lexicon: 'module', 'module name', 'compilation unit',
+  'module reference' and 'namespace'
+
+A more precise definition of the names that are used in the
+document. If you are familiar with the usual OCaml definitions, you
+can skip this section. The important point is the distinction between
+'module' (a semantic object of the OCaml language, designed in
+a program by module names, paths and references) and a 'compilation
+unit' (some data on the filesystem, representing a part of an OCaml
+program, either in source or compiled form).
+
+- A 'module' is a semantic concept of the OCaml language. Roughly,
+  it's a record whose components are addressed by identifiers rather
+  than labels. It has has a type/signature, and can carry types,
+  exceptions and submodules as well as values. I won't consider
+  functors in this summary -- though they may be important/interesting
+  to consider in a complete proposal, as Nicolas suggested.
+
+- A 'module name' is an OCaml syntactic object referring to
+  a module. Lexically, it is a capitalized OCaml identifier.
+
+  Module names are usually considered as parts of 'module paths', that
+  is sequences of '.'-separated module names, describing a module as
+  a submodule in a hierarchy of nested modules. The current synthesis
+  won't have an use of the "module path" concept (except when defining
+  the semantics of the existing `open` construct). We are interested
+  in the relation between module names and compilation units, and only
+  the head module name of a path may refer to a compilation unit, are
+  those cannot be nested.
+
+  I will use 'M' as a metavariable to denote module names.
+
+- A 'compilation unit' is a file containing OCaml source code, meant
+  to be passed to the compiler. Note that it is really "a chunk of
+  OCaml code", we could imagine referring to compilation units using
+  URLs, or some units being stored inside a database or internal IDE
+  representation.
+
+  I will use 'U' as a metavariable to denote the path of a compilation
+  unit.
+
+  In the current semantics of the OCaml language, and in all reviewed
+  proposals, each compilation unit also implicitly gives birth to
+  a 'module', whose members are all toplevel declaration phrases of
+  the compilation unit. In the current semantics, the 'module name' of
+  this module is implicitly determined by the source file's path in
+  the filesystem (the capitalized basename); also called 'unit name'
+  in the OCaml manual).
+
+  I will denote by 'mod(U)' the module name derived from the
+  compilation unit path U.
+
+  The OCaml manual
+  (http://caml.inria.fr/pub/docs/manual-ocaml/manual020.html)
+  considers a compilation unit to be defined by both the .ml file and
+  its extra-linguistically related .mli file. In practice, both could
+  be freely moved around (a .ml alone determines an implicit
+  signature, and .mli alone can be compiled and used as interface) and
+  this was considered in the present discussion, so I refined here the
+  notion of compilation unit to a single file. We could speak of
+  'interface unit' and 'implementation unit' to distinguish them. We
+  could similarly distinguish .ml and related .cmo ('source unit' and
+  'compiled unit'?) but there is no risk of confusion in practice.
+
+- A 'namespace' is a new concept of the OCaml language, that is being
+  defined by the various proposals. Roughly, a namespace is an
+  identifier (whose syntax is proposal-dependent) that refers to
+  a place where compilation units live; the name and the "place" are
+  considered one same thing. Namespaces are 'open': there is no intra-
+  or extra-linguistic way to list *all* the units present in a given
+  nameplace, it is only possible to say that some specific modules
+  (between others) live in a given namespace.
+
+  I will use 'N' as a metavariable to denote namespaces.
+
+  In my abstract syntax, I will describe namespaces by ':'-separated
+  lists of lowercase words (for example, std:data). There is also an
+  empty namespace ε, and we equate N:ε = ε:N = N.
+
+  All proposals add a new way to refer to a module in OCaml code : it
+  is possible to prefix a module name by a namespace : N|M.
+
+  Of all the considered proposals, only Alain's doesn't explicitely
+  use a concept of 'namespace'. I will still use the 'namespace' name
+  to designate a concept of Alain's proposal (in-code references to
+  'namespace maps'), as it is consistent with the other proposals, in
+  particular Nicolas's which is very close to Alain's.
+
+  Note that this is just abstract syntax. Concrete syntax choices
+  differ between proposals (most of them use '.' instead of ':' and
+  '|', Alain uses '..' for '|', etc.).
+
+
+## Motivation for the various proposals :
+
+The motivation for the 'namespace' proposals is to solve issues with
+the current way the OCaml toolchains resolves module references
+(module paths in the semantic world of OCaml program) by search of
+compilation units (in the pragmatic world of the filesystem). This is
+an 'extra-linguistic' aspect of the language.
+
+The current toolchain searches for compilation units whose unit names
+correspond to the toplevel module names (the head module names of
+module paths) used in the OCaml program being processed.
+
+  http://caml.inria.fr/pub/docs/manual-ocaml/manual022.html#toc87
+
+There is an extra-linguistic concept of "load path", which is a *set*
+of filesystem directory paths defined at each tool invocation by
+configuration, shell environment, and the passing of "-I dir_path/"
+options to the tool. For each free toplevel module name,
+a corresponding interface compilation unit is searched in the load
+path.
+
+The main defect of the current scheme is that there may be unit name
+conflicts in the search directories : if two libraries whose location
+is included in the search path have a compilation unit with name Foo,
+the reference Foo is ambiguous and the toolchain will choose either of
+them arbitrarily without letting any choice to the programmer -- there
+is no way she could to any of those two unambiguously. OCaml code
+providers do not have the discipline to uniquify unit names; that
+could be inconvenient, especially when using them in OCaml code. There
+is no idiomatic way to make this less heavy, and existing codebase
+have not taken unit name contention into account.
+
+All proposals discuss the following question : how to associate OCaml
+module references to compilation units in a way that is more easy to
+control and more resilient to unit name conflicts? The module
+references prefixed by 'namespaces' should behave better.
+
+Some of the proposals also adress tangential issues such that:
+- providing dependency information to the toolchain, in particular so
+  that `ocamldep` continues to work correctly
+- `open`ing name hierarchies and importing opening/renaming/shadowing
+  decisions (at the semantic level of OCaml programs)
+
+## Compilation unit resolution: a unified two-steps presentation
+
+The current OCaml compiler interleaves two different aspects:
+- type-checking of the source file currently being processed
+- filesystem lookups to decide which compilation units could
+  correspond to a free module reference.
+
+However, it is also possible to define the semantics in two steps,
+a first search pass to collect/define an initial "compilation unit
+environment" mapping module references to compilation units, and
+a second search-free type-checking pass. This decomposition makes
+comparing different proposals easier.
+
+A compilation unit environment is built by the following procedure:
+- iterate on all directories present in the load path
+- for each directory, iterate on all the compiled interface
+  compilation units (.cmi) in the directory
+
+- for each such unit U, add the association (ε|mod(U) -> U) to the
+  compilation unit environment (ε is the empty namespace).
+
+This first pass builds a compilation environment. It does not depend
+on the program being typechecked, but environment variables and `-I`
+options passed to the compiler may influence the load path. After this
+first pass, the current source can then be typechecked: when
+encountering a free module name, the typechecker access the
+compilation unit bound to it in the compilation unit environment. In
+an implementation-specific way, it extracts the signature from the
+compilation unit, and add this interface in the 'typing environment'
+of the current program (not that typing environment and compilation
+unit environment are two distinct notions: the typing environment
+relates OCaml program identifiers to types and signatures), and
+typechecking then proceeds as usual.
+
+This is only a description of the semantics, not of an
+implementation. You could imagine a naive implementation with a first
+pass strictly building an environment, or the current
+search-on-occurrence implementation which can be seen as an
+optimization of first, making environment building lazy.
+
+When trying to compare and relate the different proposals,
+I discovered that they could be articulated around this compilation
+unit environment process. More specifically, they suggest new ways to
+build the initial environment:
+
+- when adding the binding (R -> U), do not automatically derive the
+  module reference R from the unit name, but use a module reference
+  R determined by other means (a configuration file in the directory,
+  etc.)
+
+- when traversing a directory, do not handle all compilation unit but
+  only some of them as defined in a configuration file, etc.
+
+- instead of searching a load path, using arbitrary mapping as defined
+  in a mapping file passed to the compiler...
+
+## Semantics of the "opening" namespaces: an `open-namespace` construct
+
+This two-pass semantics allows a simple explanation of `open`
+semantics for namespaces. The current semantics of `open <expr>`
+cannot be explained as an action on the `module environment`, but on
+the complete typing environment of an OCaml program: it looks for the
+module (OCaml semantic object; not necessarily associated to
+a compilation unit, eg. possibly a submodule of a compilation unit, or
+result from a functor application, etc.) denoted by the expression
+<expr>, and adds all its declarations to the environment.
+
+We define a new `open-namespace N` construct, reflecting constructions
+used in the proposals (again, this is not a choice of concrete syntax;
+all propositions but Alain's only use `open`). `open-namespace N₁` is
+defined by its action on the compilation unit environment: for each
+binding of the form (N₁:N₂|M -> U) in the environment, (N₂|M -> U) is
+also added to the environment.
+
+Remark: with the described semantics, `open-namespace N` never fails:
+it filters environment bindings to process those prefixed by N, and do
+nothing if this set is empty. It could be sensible to add a warning,
+but raising an error would break the "namespace are open" intended
+semantics.
+
+
+# Part 2: How does the current proposals relate module references to
+   compilation units?
+
+In Alain's and Nicolas's proposal, new mappings are added by files
+mapping OCaml identifiers or path to compilation units (given by
+a filesystem path). Those mapping files:
+- may be found in the search path (Alain's proposal)
+- may be passed explicitely to the tool (Nicolas's proposal)
+
+In Alain's proposal, the 'namespace' N associated to all those mapping
+files is derived from the filesystem path of the mapping file. Each
+line of the mapping files associates a module name M to a compilation
+unit U, but the compilation unit environment is really enriched with
+the binding (N|M -> U). For example, neglecting concrete syntax
+difference, the file `ex.ns` containing `Foo: /tmp/a.cmi; Bar:
+/tmp/b.cmi` would enrich the environment with (ex|Foo -> "/tmp/a.cmi",
+ex|Bar -> "/tmp/b.cmi").
+
+In Nicolas's proposal, the (compiled) mapping files is already
+a sequence of bindings (R -> U), which are added as is, without any
+influence from the mapping file's filename.
+
+In Fabrice's and Martin's proposals, the environment-building
+pass does not act the same on all directories of the search path,
+depending on whether the directory contains a distinguished
+configuration file (Package, ocaml.ns). If not, the current semantics
+is used (all .cmi are added to the environment). Otherwise:
+
+- in Martin's proposal, the Package file explicitely lists the
+  compilation unit U¹, U²... Uⁿ exported (I suppose the directory
+  isn't searched for other compilation units), with an optional
+  namespace N (default value ε). The mappings (N|mod(U¹) -> U¹),
+  (N|mod(U²) -> U²)... (N|mod(Uⁿ) -> Uⁿ) are added to the
+  environment.
+
+- in Fabrice's proposal, the ocaml.ns file only specifies the
+  directory-common namespace N. It is searched for compilation units:
+  for each compiled interface compilation unit U in the directory,
+  (N|mod(U) -> U) is added to the environment.
+
+In another variant of Fabrice's proposal, there is no configuration
+file, but each compilation unit U may optionally specify a namespace
+N. In this case the repository is scanned as usual, and (N|mod(U) ->
+U) is added to the environment.. Should the usual (ε|mod(U) -> U)
+binding also be added? This is a flexibility point of the proposal;
+Fabrice suggests to also bind it only in the case where the currently
+processed unit does not mention namespaces ("compatibility mode").
+
+Once the compilation unit environment is built, typechecking proceeds
+as usual in all proposals.
+
+When a proposal defined an `open` construct, I believe it always
+coincided with the behavior of the `open-namespace` construct defined
+in part 1. Note that some proposals use the same syntax for modules
+and namespaces: when encountering the concrete code `open Foo`, it is
+unclear if Foo is a module or a namespace, and the semantics differ;
+ambiguity resolution rules are needed. In Alain's proposal, there is
+a distinct `open namespace Foo` syntax which resolves the ambiguity.
+
+A namespace-aliasing construct could be treated as a compilation unit
+environment transformer, just as we handle `open-namespace
+N`. `alias-namespace N₁ to N₂` would add, for all bindings of the form
+(N₁:N -> U), a new binding (N₂:N -> U). `open-namespace N` is then the
+special case `alias-namespace N to ε`.
+
+
+# Part 3: How should we evaluate and compare the different proposals?
+
+## What they compare against: uniquifying file names
+
+Alain made an extremely simple proposition that doesn't request much
+change from the current behavior. He only suggested that library
+writers adopt the convention to use only 'unique' file names, to avoid
+any conflict issue.
+
+To avoid having to use painfully long module names in an OCaml
+program, Alain suggested to introduce a module name aliasing syntax;
+which would silently give a module name alias to an existing module
+path. Such renaming could also be included and shared in separate
+files, as requested by Yaron Minsky and proposed by Jacques Garrigue.
+
+This proposal is not directly discussed further in my synthesis. As
+applying it would require changes to existing codebases, the consensus
+seems to be that it is too impractical. However, it is good to keep it
+in mind when evaluating other proposals, as a 'placebo proposal' to
+compare against.
+
+Remark: it is tempting to try to define the semantics of module
+renamings as action on the compilation unit enviroment (from ε|M₁ to
+ε|M₂), but I think they rather belong, as `open` on modules, to the
+typing environment. In particular, you may want to alias a module
+*path* to a module name, to adress submodules directly. This would
+require maintaining separate 'path substitutions', as done in a recent
+article by Hyeonseung Im, Keiko Nakata, Jacques Garrigue, and Sungwoo
+Park, for entirely different purposes.
+
+
+## Subjective comparison: User-side resolution of conflicts
+
+Disclaimer: while the previous sections were purely an objective
+presentation of the different proposals in a way that hopefully made
+them easier to compare, the present section tries to evaluate each
+proposal on an important corner case, a module reference
+conflict. I partly discuss 'naturalness' or 'convenience' of
+different solutions, and it is therefore subjective and possibly
+misjudged.
+
+One important criterion for the namespace proposals, as highlighted by
+Jacques Garrigue, is whether the *users*, rather than the producers,
+of two libraries are able to resolve a naming conflict.
+
+Note that this is not a *necessary* feature for a namespace
+proposal. In particular, the 'placebo' proposal (just use long,
+hopefully-unique names) doesn't have any way to deal with this: if
+your names were not long and unique enough, well, it's your fault;
+just ask the code producers to rename them (or recompile them locally
+under a different filename, which makes you a code producer). It's
+less of a problem if names are, by convention, long and hopefully
+unique than it is currently, with short common names.
+
+Fabrice's proposal does not handle conflicts: once your compiled unit
+has a namespace recorded, you cannot change it from the code user
+side. If two compiled units are in the search path and have recorded
+the same namespace and module name, there is a conflict that, if I'm
+not mistaken, the user cannot resolve alone.
+
+Alain's and Nicolas's proposals make it easy for the user to change
+name->unit associations in case of conflict, because it is their basic
+level of granularity. If the current namespace mapping attempts to
+bind foo/mod1.cmi and bar/mod2.cmi to the same module reference, just
+add two new distinct references to be able to refer to them
+unambiguously. Nicolas's proposal is slightly more flexible as it
+allows easy renaming of whole mappings: if code providers A and
+B provide two respective namespace mapping files "foo/list.mln" and
+"bar/list.mln" that both bind compilation units to the data:list
+namespace, and you want a stronger distinction, whether some of those
+units are identical (conflict) or not, you can write your own
+"my/list.mln" mapping file, following Nicolas's proposal horrible (:-)
+surface syntax:
+  module a = struct include "foo/list.mln" end
+  module b = struct include "bar/list.mln" end
+And thereafter use the desambigued namespaces a:data:list b:data:list.
+
+Alain's proposal doesn't have this level of abstraction (namespace
+maps are flat, first-order mappings), but he is very explicit that
+namespaces are to be processed by automated tools, that could achieve
+similar multi-remappings.
+
+Martin's proposal is a bit half-way on this point: if the directories
+foo/ and bar/ both export mod.cmi *and* use the same namespace, you
+could copy them to foo_copy/mod.cmi and bar_copy.cmi and use a two
+user-defined Package files to remap those interfaces in two distinct,
+unambiguous namespaces. While this is fundamentally the same operation
+as in Alain's or Nicolas's proposal situation, this feels a bit
+awkward as the proposal was clearly not optimized for this use case
+(compilation unit are not expected to change packages, hence the
+implicit directory/unit relation). Still, it can be done purely from
+the user side.
+
+
+## Aspects not discussed
+
+I deliberately left out some of the proposals aspects and surrounding
+discussions from the current synthesis.
+
+- Effect on tools (ocamldoc, ocamldep, ocamlbuild, make, omake,
+  ocp-build...). I'm not familiar with the tooling aspect of those
+  proposals. Alain suggest that tools needing to designate
+  a compilation unit U systematically use the "current semantics"
+  designation (mod(U)), and let namespace-aware post-processing tools
+  do eventual renamings to module references as appropriate. Unless
+  tools actually keep the full reference R and only display mod(U),
+  this would make those tools output less conflict-resilient: possible
+  ambiguity strikes back.
+
+- Dependency analysis (really a sub-point of the above). Some proposals
+  provide tools for dependency analysis. I concentrated here on the
+  "risk of module reference conflict" + "resolution of unlikely
+  conflicts" aspects. I think dependency analysis should be discussed
+  independently.
+
+- Intra-program mechanisms to act on the module
+  environment. Surprisingly, most proposals where concentrated on the
+  extra-linguistic question of how to relate compilation units to
+  module names, not to operations on module names themselves. Only
+  Alain's 'placebo' proposal discusses this aspect, with Jacques
+  Garrigue's intervention. Nicolas feels it should be discussed
+  independently, and Fabrice proposes a namespace-aliasing
+  construct. As I discussed earlier, module path substitutions are
+  outside the scope of the compilation unit environment.
+
+- Subtleties of when to use the 'new' semantics, assuming namespaces,
+  or when to fall back to the current semantics. The details are a bit
+  hairy and differ a lot between the different proposals. I think this
+  is rather independent from the interest of each. Note that Alain's
+  choice to have a distinct namespace / module-path separator makes
+  this a non-issue, the problem is when the same extended identifier
+  may designate both a module path or a namespaced module reference.
+
+- Eventual relations with `pack` and functors. Nicolas expressed the
+  idea that his proposal might evolve to express the "functor packing"
+  construct independently suggested by Fabrice. I have not discussed
+  this aspect at all, and don't know whether/how it relates to the
+  compilation unit environment presentation.
+
+## What next?
+
+My goal in publishing this synthesis is to advance the discussion in
+a good direction. I'm interested by your feedback on this synthesis:
+
+- Does it faithfully represent your proposal? Is the "formal" part
+  correct? Are some other aspects of missing? Could we describe them
+  in this setting?
+
+- Does the current presentation capture the idea of 'namespaces'? Are
+  there some concrete problems that are not expressible in this
+  framework?
+
+Besides, I think this could be a good tool to evaluate and evolve the
+existing proposal. A natural idea is to try to make the union of all
+the "environment building operations" used in the different proposal,
+and see whether it is still satisfying, what is missing or should be
+left out. I will eventually try to describe such an approach (help and
+suggestions appreciated), but I wished to publish and discuss this
+synthesis first.
+
+Finally, I have two remarks about aspects of the synthesis that could
+warrant further elaboration. The first is that this two-pass
+description actually results in a *closed environment* of namespaces
+at type-checking type. While in principle namespaces are considered
+open (all operations of the current semantics and the proposals only
+add new mappings to the environment), after we have an environment we
+can precisely enumerate all available compilation units and their
+namespaces. In particular we could derive a module from a given
+namespace N : it would contain, for all (N|M -> U) in the environment,
+the module derived from U, under identifier M. This could be used to
+give a meaning to, say, giving a namespace to a functor. I have
+discussed this with Nicolas, but am unsure which conclusions to draw:
+my gut feeling is that it is not a good idea.
+
+The second remark is that the unified presentation could be considered
+as defining a "language" for namespace files. In Nicolas's proposal it
+is already visible that namespace mapping files are some form of
+"source code", even if not part of usual OCaml compilation
+units. Alain, on the contrary, took great care to present its mapping
+files as *data* rather than programs, possibly the output of
+preprocessing tools. In Fabrice's proposal, the "language" to talk
+about namespaces is quite restricted and used (in some variants of his
+proposal) at the beginning of compilation units; filesystem and
+compilation option hints are also used. In Martin's proposal, as in
+the current semantics, the construction of the environment is
+completely implicit and by-convention, directed only by passing -I
+options to the compiler. How explicit and expressive do we want to be?
+
+
+
diff --git a/nicolas.text b/nicolas.text
new file mode 100644
index 0000000..f672e6a
--- /dev/null
+++ b/nicolas.text
@@ -0,0 +1,127 @@
+A proposal by Nicolas Pouillard:
+
+> This proposition would introduce two new kind of files, let's call
+> them .mln and .cmn but as we will see these names are not the best
+> ones.
+>
+> In a .mln file we have a tiny OCaml like language where we can
+> describe modules (and maybe functors).
+>
+> Here is the language for .mln files:
+>
+> m ::= module M = struct m end
+>    | module M = filepath
+>    | m*
+>    | include filepath
+>
+> As an example, let's follow this session:
+>
+> $ cat base_std.mln
+> (* Std is a bit like a -pack but without the size/granularity issue. *)
+> module Std = struct
+>  (* For each unit we describe where to find the relevant source files. *)
+>  (* Internally Array and List are not fields of Std but are toplevel
+>     units: Std.Array and Std.List *)
+>  module Array = stdlib/array
+>  module List  = stdlib/list
+> end
+>
+> $ cat ext_std.mln
+> (* Modules described in .mln files follows an merge policy.
+>   So we are not in conflict with the previous Std module
+>   but extending it. *)
+> module Std = struct
+>  module List = struct
+>    (* Notice that Lazy will not be compiled as a field
+>       of List but as a toplevel unit of name Std.List.Lazy.
+>       Notice as well that the name for the file is not
+>       relevant here. *)
+>    module Lazy = ext/llist
+>  end
+> end
+>
+> $ cat std.mln
+> include base_std
+> include ext_std
+>
+> $ cat ex.ml
+> (* No extension to the main language is required.
+>   While improving the expressiveness of `open' could
+>   be useful this is matter for another proposal. *)
+> open Std
+> open List.Lazy
+> (* ... *)
+>
+> # Compiling .mln files produces .cmn files.
+> # We can easily merge .cmn files by concatenating them.
+> # However we keep them separated here.
+> $ ocamlc -c *.mln
+>
+> # Three .cmn files where built
+> $ ls *.cmn
+> base_std.cmn ext_std.cmn std.cmn
+>
+> # Compiling the interface and implementation of the Std.Array unit
+> $ ocamlc -c std.cmn stdlib/array.mli
+> $ ocamlc -c std.cmn stdlib/array.ml
+>
+> # alternatively one can call for the build of a unit by its module name
+> $ ocamlc -c std.cmn Std.List
+>
+> # Building a library for base_std
+> $ ocamlc stdlib/array.com stdlib/list.cmo -o base_std.cma
+>
+> $ ocamlc -c std.cmn ext/llist.mli
+> $ ocamlc -c std.cmn ext/llist.ml
+>
+> # Compiling and linking our example file
+> $ ocamlc std.cmn base_std.cma ext/llist.cmo ex.ml
+>
+> Now let's look at the .cmn files, there contents is close to Alain's
+> proposal, namely a list of lines, where each line associates a
+> module path (not just a module name) and a base file path (not just
+> a base file).
+>
+> c ::= (module_path ':' blank* file_path '\n')*
+>
+> Examples:
+>
+> $ cat base_std.cmn
+> Std.Array: stdlib/array
+> Std.List: stdlib/list
+>
+> $ cat ext_std.cmn
+> Std.List.Lazy: ext/llist
+>
+> $ cat std.cmn
+> Std.Array: stdlib/array
+> Std.List: stdlib/list
+> Std.List.Lazy: ext/llist
+>
+> Notice that any conflicting declarations will be considered as an
+> error.
+>
+> I've ideas on how to extend this to functors and this would fill the
+> same need as the "big functors" feature from Fabrice.
+>
+> The pros of this propositions are the following:
+>  * Tools are kept simple. They will have to read .cmn files but
+>    they are kept flat and simple.
+> * In particular ocamldep becomes correct if fed with the .cmn files
+>    for complete environment and using a strict mode.
+> * When using exclusively this mode, there is no need to pass -I
+>    flags to the different tools only .cmn files which are more
+>    robust. The behavior of the compiler then becomes simpler to
+>    describe. The .cmn files are concatenated and form the initial
+>    environment.
+> * No addition of a concept different from modules (I was arguing the
+>    opposite previously but I think that if we want to open
+>    namespaces then this solution seems satisfying).
+>
+>  The cons I see are the following:
+> * A new source language
+> * This could create confusion w.r.t the compilation of
+>    modules. Inside a compilation unit modules are like records and
+>    outside they are compiled field by field.
+> * What can we do with `Std' stays an open question.  If we want to
+>    keep things light I would only allow opening and projections.
diff --git a/related.text b/related.text
new file mode 100644
index 0000000..47aca0a
--- /dev/null
+++ b/related.text
@@ -0,0 +1,155 @@
+While I have not taken it into account as a proposition, Alain's
+'placebo proposal' and Jacques's intervention are also
+related:
+
+Alain Frisch:
+
+> 1. Compilation units still must have globally unique file names
+> (typically enforced in library through prefixing, e.g. MyDataLib_List.ml).
+>
+> 2. A module renaming construction in the language: "open N as M" (and
+> "let open N as M", and also "open N as M" in signatures). This is
+> convenient, but not strictly necessary for the rest of this proposal.
+>
+> 3. In order to share module renaming definitions, one can put them in
+> dedicated .ns text files which only declare such renaming (either with
+> the same syntax "open N as M" or maybe a simpler version "M = N"), and
+> pass a reference to these files to the compilers (and other tools) on
+> their command-line. The compilers behaves exactly the same as if the
+> renaming definitions had been prefixed to the compiled source code,
+> except maybe for error messages (they could use the info in .ns files to
+> create shorter names for toplevel modules).
+>
+> 4. Compiled files (.cmi, .annot) always refer to real module names (i.e
+> "open N as M" forces M to be rewritten to N).  (Variant: in addition to
+> their content using real names, these files are extended to remember
+> about the external module renaming definition used during their
+> compilation.)
+>
+> 5. ocamldep can also accept .ns files, but it always output real module
+> names.
+>
+> 6. ocamlfind can be adapted to pass the .ns file declared in a library's
+> META files when this library is used.
+>
+> 7. ocamldoc accepts .ns file in order to use shorter names for toplevel
+> modules.
+>
+>
+> What this proposal does not really address if the scenario where one
+> would like to use two versions of the same library in the same project
+> (although if this is really really needed, one could recompile one
+> version of the library after having changed the module filenames and the
+> .ns file).
+>
+> Apart from this scenario, I believe this proposal cover most of the
+> expected advantages for namespaces.
+>
+> Some extra advantages:
+>
+> - No change to the language syntax (except for 2, which is optional and
+> very minimal) ---> No need to adapt syntactic tools such as editor
+> modes, syntax highlighters, indenters, camlp4.
+>
+> - It is never necessary to use the new feature: a program can always use
+> the full module names even if libraries are shipped with .ns files.
+> Fewer notions to understand to get a good understanding of the language.
+>
+> - Naming decision can be done by library authors (if they ship .ns
+> files), but can also be tweaked by library users. Library authors are
+> only required to use unique enough names (and packagers can do that if
+> needed, simply by renaming the source files and adding some .ns files).
+>
+> - No need to change the build system tools. Only minimal changes to the
+> build systems for projects (i.e. the Makefile/OMakefile, etc). E.g. if I
+> want to use a third-party library in my complex project managed with
+> omake, I only need to pass extra arguments to the compiler (.ns files),
+> but all the logic to compute dependencies (by parsing the output of
+> ocamldep) is unaffected. (Or I could decide to use the real module names
+> for some time, if for some reason I depend on a build system which would
+> not let me pass these .ns files.)
+>
+> - No need to change other tools, although they might be adapted to
+> improve the user experience. Example: we have a very simple dead-code
+> detector which parses all the .annot and all the .cmi for our project in
+> order to find exported values which are never used; this would work
+> out-of-the box, but we could put more energy and decide to make it aware
+> of .ns (or of the extended info if the variant in 4 is chosen) in order
+> to have a nicer output.
+>
+> - No complex interactions with the filesystem hierarchy, no new
+> ambiguity resolution algorithm, and no hard-coded conventions.
+
+
+
+A further remark by Jacques Garrigue:
+
+> I quite like Fabrice's proposal (actually I prefer it to Alain's,
+> which seems harder to use).
+> But we may still explore some other approaches.
+>
+> Personally, I think that there are two problems here:
+>
+> * the ability to provide a mapping from short names to qualified names,
+>   without necessarily having to include all the compilation units
+>
+> * the need to compile modules with qualified names to avoid conflicts
+>
+> I would rather leave the second problem as implementation specific
+> (i.e. the compiler should be able to distinguish modules with the same
+> name), and concentrate on the first one.
+>
+> Reading the proposals, they seem to tend to use either extra flags or
+> external files.
+> What about something _simple_ included in the language.
+>
+> I.e. just allowing to write
+>
+> module M as Path
+>
+> which means that when we meet M we expand it to the qualified
+> version of Path (which the compiler should generate according to the
+> context)
+>
+> Taking the example of Core, we would have
+>
+> In Core.mli:
+>
+> module List as Core_list
+> module Option as Core_option
+> module Unix as Core_unix
+>
+> Now it would be enough for the client to do
+>
+> open Core
+>
+> and get all the translations automatically.
+>
+> Note that you only need an mli, since there is no code,
+> only translation information.
+>
+> In a more advanced version, it could be
+>
+> module List as List
+> module Option as Option
+> module Unix as Unix
+>
+> with the compiler detecting at compile time of core.mli
+> that it should use the List, Option and Unix in the current
+> directory. However there is a difficulty here, since
+> we need to know which List, Option and Unix we should use
+> just by looking at their cmi's, not their cmo's.
+> A way to do that would be to include the information
+> there by using -for-pack.
+>
+> To sum up, one would have to write:
+>
+> ocamlc -for-pack JS.Core -c list.mli
+> ocamlc -for-pack JS.Core -c option.mli
+> ocamlc -for-pack JS.Core -c unix.mli
+> ocamlc -c core.mli
+>
+> So this ends up to be the same thing as using a package,
+> but without making it monolithic (one builds a cma, not a cmo),
+> and with more flexibility about the exported naming of the modules,
+> the -for-pack being only to avoid conflicts.
ViewGit