[ocaml-platform] Followup to Leo's proposal

Yaron Minsky yminsky at janestreet.com
Wed Mar 13 12:56:18 GMT 2013


On Wed, Mar 13, 2013 at 7:44 AM, Leo White <lpw25 at cam.ac.uk> wrote:
>> Having
>> namespace opening be a special-case thing that only happens on the
>> file level and that is hidden from the source just seems like an
>> unfortunate special-casing of a namespace manipulation tool (like let
>> and open) that should be available generally.
>
> Just to be clear I'm not proposing to have namespace opening at file
> level, just the hidden opening of modules.

Sorry, my terminology is perhaps a bit confusing.  The way I'm talking
about it, opening a module, opening a namespace and let bindings are
all manipulations of the program's name-space.  I guess that's a
terrible way of saying it.  Should I call those manipulations of the
naming enviroment?

In any case, I want to do as many environment manipulations in the
source as possible, and moving module opens to the build system seems
like a regression for our use-case.

>>>
>>> I think the awkwardness is more related to how you treat things like:
>>>
>>>    Core#Foo
>>>
>>> where Foo might be a sub-module of Core#Common.
>>
>> Can you elaborate a bit?  Why is this case problematic?  I can kind of
>> see why this is weird, but other than making an explicit requirement
>> of having an ordered semantics (which to me seems like the right
>> answer anyway, since it's more in tune with how OCaml's other
>> namespace manipulation operators work), it seems fairly
>> straight-ahead.  But I'm probably missing something important.
>
> We should propbably stop calling this idea "auto-opening" because it is
> really about allowing modules to be "included" within a namespace. This
> is not a small change to the semantics. Without "auto-opens" namespaces
> are simply a mechanism for controlling the names of compilation units,
> with them they become a partial replacement modules: able to contain
> values, types, exception, etc. Having two different features that
> substantially overlap is normally a bad idea since it can cause a lot of
> confusion.
>
> Without auto-opens the namespace system is completely oblivious to the
> actual contents of modules. With auto-opens the compiler must look
> inside modules to work out whether "Core#Foo" refers to a member of Core
> or a sub-module of one of its auto-opened modules.
>
> Also, an ordered semantics is not for free. It makes having a
> namespace defined in multiple places (as with users adding to existing
> namespaces) much more fragile.
>
> I think this is why people are reluctent to include automatically opened
> modules in the namespaces proposal: it is quite a large change to the
> semantics to handle a problem that is only likely to affect a few
> libraries.
>
> However, I think that I can see a way to avoid the problems of an ordered
> semantics and possible "Core#Foo" conflicts.
>
> The basic idea is to define a module named "Core" containing the values
> that you would like automatically opened, as well as a namespace named
> "Core". Then you provide some kind of opening operation that opens both
> the namespace and the module named "Core".
>
> This avoids the problem of ordering members of namespaces, since there
> should only be one module called "Core". Technically there could be
> multiple "Core" modules in the search path, but we simply use the first
> one we find just like normal modules.
>
> It also avoids the issue of "Core#Foo" conflicts, since "Core#Foo" must
> refer to the "Foo" member of the "Core" namespace, while "Core.Foo"
> would refer to the "Foo" sub-module of the "Core" module.
>
> This could be added to a namespaces proposal in a number of ways. For
> example we could allow modules named "Core#_" (or core-_.ml) to be
> defined. These modules could be refered to directly in programs as
> "Core". When the compiler encouters a "open namespace Core" construct it
> first opens the "Core" namespace, and then it searches for a module
> named "Core#_" and opens that as well.

I think what you've come around to is pretty similar to what I had
intended in the first place when I was saying "auto-open modules".  In
particular, you're proposing having a module "Core" associated with
the namespace "Core", and that the two are automatically opened
together.  My thought was to do something that is only slightly
different from that: to be able to associated a list of modules L with
a namespace N, such that opening N automatically opens L.  That seems
broadly speaking less confusing and more flexible, rather than relying
on name collisions.

I think this specifies the role of modules in "open namespace N" and
"let open namespace N in expr".  What seems to be in contention is the
semantics of N#M.  I think Leo and Alain are proposing that this be
limited to M being another module or namespace, and that it would
ignore the module opens.  I would have thought it more natural for N#M
to translate to "let open namespace N in M", so that M could be either
a module or a value, and could be present in the namespace N or in the
list of modules that is auto-opened with N.

What is the argument in favor of the semantic distinction between N#M
and "let open namespace N in M"?

y


More information about the Platform mailing list