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

Didier Remy Didier.Remy at inria.fr
Tue Feb 26 22:03:52 GMT 2013


Yaron,

>> Do you really need this level of granularity?  I'd like to think of
>> modules as the smallest compilation unit.  Can you give us examples of what
>> you'd like to do with value manipulation?
>
> I think we do.  What we want is essentially the same thing that we
> need to do when OCaml opens Pervasives by default.  We simply have
> another module that we wish to open by default.

This is quite different than cherry-picking values from a module.  Also open
is a bit misleading here, because it must behaves like an include.  While
open brings all subcomponents in scope but does not evaluate them, include
must evaluate (use) all the definitions and binds them in the current
structure.

This is quite different from what happens when building namespaces: when a
new definition shadows an older one in a namespace, the older definition
will not be visible by the linker and will not be evaluated.

"Include-on-open" (called flat-acccess by Gabriel) is doable as Gabriel
explained, and would generalize the behavior of pervasives, but it is
another mechanism than just building a namespace (because it also _uses_ a
module).

> There are two reasons for this: the first is to open at the top-level
> some constructors and values that are very commonly useful.  Much as
> pervasives has None and Some from option available everywhere, we have
> Ok and Error from Result.t available everywhere.

Fine.

> Another reason is to shadow values from other modules.  Core.Std hides
> various values from Pervasives that we view as harmful.  For example,
> we hide ==, and instead expose phys_equal.  (We think == is too
> confusing to people from other languages.)

This example is different I think, and perhaps another solution could be used.
My understanding is that you wish to have your own version of stdlib, say
stdlib_minus_plus.

Why don't you create a new module stdlib_minus_plus that includes stdlib
with a restricted safe interface (so that bindings "minus" will be evaluated
but not visible) and then add your own safer definitions "plus", bind the
resulting module to some namespace Core#stdlib and then use your own version
of Core#stdlib instead of the original stdlib?

It seems that you wish Core.std to be only a diff against the original
stdlib and not a patched copy. Is this the case? Why it is important?

> Similarly, Async hides blocking operations that are available in
> Core.Std, like print_string, so when you write:
>
>     open Core.Std
>     open Async.Std
>
> those problematic values are hidden from.

Isn't this fragile? for example, what happens if the user mistakenly writes
these two lines in the other order? If Async.Std _must_ hide values of
Core.Std for safety reasons (for instance to avoid blocking), why is it not
returning a patched copy of Core.Std with these values overridden instead of
relying on the user to open modules in the right order?

> think, to make every single file that uses Core have to change from:
>
>     open Core.Std
> to
>     open namespace Core.Std
>     open Core.Std.Common
>
> or whatever it would need to be.

I don't see what you mean here.

     Didier


More information about the Platform mailing list