[ocaml-platform] on the need and design of OCaml namespaces

Wojciech Meyer wojciech.meyer at gmail.com
Fri Mar 1 01:17:56 GMT 2013


So we have two problems related to the order of the namespaces being open:

1. when merging namespaces, the order is important because of the
   possible overrides of the names
2. when opening namespaces order is important because of the order side
   effects modules might have.

The merging happens in two cases:
. when namespaces is being open in the OCaml code, withing the `open';
. in .ns file as explicitly when constructing namespaces.

The side effects happen in just single case, when the namespace is
brought to the scope - so that means this is only known when everything
is already properly merged, so it's not a problem.

Let's say for this hierarchy of namespaces:

Core
      Pervasive
      Std
      Extras
        Async
        TypeConv

but apart from that we could also have:

CorePkgs
      Pervasive
      Std
      TypeConv
      Async

we can easily predict how the modules will be open, assuming all the
namespaces below Core are auto-opened, however we could equally say:

  namespace alias Core = Core # { Pervasive, Std, Extras }
  open Core

  open Core # *

  open Core # **

  open Core # Extras # *

  open CorePkgs
  open CorePkgs # *

which roughly equals the syntax:
  use core.ns

Then with this syntax we are able to open Core and bring it to scope
with all the side effects we would expect.

Given all the facts and considerations about auto-opens, I'd suggest the
alternative to have just more expressive syntax for opening namespaces.

Didier Remy <Didier.Remy at inria.fr> writes:

>> I agree with your point about settilng deep semantic issues ahead of
>> syntactic one.  I would however submit that the question of whether
>> you should:
>>
>> - Have opens in the language proper, including local opens
>> - Have renames for namespaces in the language proper
>
> Yes, this is  the minimal, and probably agreed on.
>
> The main question whether namespaces are hierarchical or flat is still not
> answered, Flat namespaces are not much of an extension to OCaml and do not
> raise many questions about their semantics.  This is the benefit of Alain's
> proposal---but also its weakness to be limited in expressiveness.
>
> If namespaces are hierarchical, the simplest model is that of a graph where
> inner nodes are namespaces, leave nodes are module objects, edges are
> names (and directed).
>
> One question raised is whether edges should also carry auto-open flags, so
> that whenever a node is opened all other nodes reachable by auto-open edges
> are also opened.  This feature is strongly desired by Yaron, but it raises
> further issues...
>
> There is no reason for having just one such edge. Indeed, the idea is to
> break big modules into smaller ones so that only actually used modules need
> to be linked. The same should hold for auto-open modules.
>
> However, since opening modules is not commutative, auto-open edges must be
> ordered.  This means that the mental model to give to the user is not just
> a directed graph with label edges whose leaves are module objects, as
> described above, but whose edges (at least those flagged auto-opened) are
> also ordered.  I think this is a bit more complicated and not so nice that
> edges need to be both ordered and named...
>
> The problem comes from module leaves.  For inner nodes one could check the
> absence of conflicting names at the end of auto-open edges when building
> namespaces so that the order of opens would not matter.  But one cannot do
> so for leaves, because modules should remain opaque to namespaces (I think),
> hence conflicts cannot be detected when building the namespace,
>
> Yet another question raised by auto-open flags, which Gabriel and I
> discussed  today is how auto-open behaves on access paths.  Assume,
> for instance, a namespace containing:
>
>         ROOT . --Core--> C --Pervasives*--> M
>                           \
>                             --Std*--> S
>
> and that the module M contains a submodule List.  Should the user always
> write Core#Pervasives#List or could he simply write Core#List, since given
> that Pervasives is auto-open it could have just written
>
>            open Core
>            List
>
> to designate module M.List. Indeed, one could expect that both
>
>         let open path in Name
> and
>         path#Name
>
> return the same object.  This way, the ordinary user would not need to know
> about the Pervasives module.  Only the expert user who wishes to open just
> the Pervasives module and not its parent will have to know its existence and
> write
>
>         open Core#Pervasive
>
> Unfortunately, this choice of semantics implies that paths must be
> interpreted in a much more complex way: path#name need not only look at the
> node at path for an edge labeled Name but also at all nodes (recursively)
> reachable by auto-open edges!
>
> With these (small) complications in mind, do we still wish to have
> auto-open edges? It this the good model?
>
> ----------------
>
> In their absence, one would have to perform the auto-opens manually, and
> the order of opens would therefore be given by the user.
>
> The reason for auto-opens is to allow the user to just write
>
>         open Core
>
> instead of
>
>         open Core
>         open Pervasive
>         open Std
>
> Perhaps, an alternative to auto-open would be to allow one to write open
> directives in .ns files as well. Then, a file myenv.ns could both build a
> namespace and pre-open some of the nodes, including some of its leaves.  The
> user could then just put something as concise as
>
>         use myenv.ns
>
> at the top of his *.ml files. And if he opens myenv.ns he will have a very
> clear idea of what names should be visible.
>
> Just an idea, which I don't like so much either.  But is shows that there
> are still important details to be thought of and choices to be made.
>
> ----------------
>
> Notice that the problem comes from the fact that leaves of namespaces are
> opaque modules (and I think modules should remain opaque to namespaces), and
> as a result conflicting interfaces of modules cannot be detected when
> building a namespace, combined with the fact that the open construct of the
> module language is not itself strict (i.e. it may override bindings) and
> thus does not commute.
>
>         Didier
> _______________________________________________
> Platform mailing list
> Platform at lists.ocaml.org
> http://lists.ocaml.org/listinfo/platform

--
Wojciech Meyer
http://danmey.org


More information about the Platform mailing list