[ocaml-platform] Followup to Leo's proposal

Leo White lpw25 at cam.ac.uk
Tue Mar 12 21:50:37 GMT 2013


Gabriel Scherer <gabriel.scherer at gmail.com> writes:

> One aspect of Leo's proposition that I found lacking is the absence of
> a precise framework that could explain the semantics of the proposed
> features and study their combination.

Certainly, before any final proposal, a precise semantics should be
worked out.

> - how to compose different "search path files" (by concatenation, I
> assume; I regret the absence of any conflict handling considerations)

Essentially, yes they are concatenated. In more detail:

When looking for a module, the compiler should work through each search
path and search path file (using the order they were given to the
compiler). It should work through each individual search path file
backwards, checking each mapping. If it finds a mapping for the module
of the form:

  Foo: "filename"

then it should use that filename. If it finds a mapping for the module
of the form:

  Foo: Bar

Then it should continue its search, but looking for Bar instead of Foo.

> - whether "-open" arguments would still be opened in absence of the
> corresponding "open namespace Core" (it looks like "yes", and that
> would be a semantics change wrt. the discussed flat-access feature)

Yes, the "-open" argument is basically unrelated to namespaces. It
simply specifies a module that should be opened in the initial
environment (just like Pervasives).

> - what happens when you write "open namespace Croe", making a typo

I think that the compiler should look in its search path for any
mappings like "Croe#Foo: 'foo.cmi'" or any files croe-foo.cmi. If it
doesn't find any then it should give an error or a warning.

> - whether each build system would have to implement its own way to
> describe which -name option are supposed to be passed to which files;
> it would be natural to pass them a description of the expected final
> compilation environment (mapping module names to compilation units),
> but in presence of -name you need to provide another mapping from
> needed-.cmi names to corresponding-.ml names, and each build system
> would need to come with its own description language for these "send
> all foo/<bar>.ml to foo-<bar>.cmi" (which looks awfully like a
> namespace description language)

I would have thought a simple variable or switch to indicate which
naming scheme was being used would suffice. I suppose some build systems
might like to support more complex name mappings using some kind of
description file. 

The important point is that if we devise some official naming
description that is in some way supported by the compiler then every
build system must be updated to support it. If we simply provide a
command-line argument then we allow the build systems to decide what and
how to support themselves.

> On a rather orthogonal point, the proposal doesn't explicitly mention
> the problem of internal module name conflicts. I assume that the
> solution is "-name", meaning that the library authors must make sure
> that the -name option they pass (or the source filename) will be
> unique among all modules used by their downstream users. As it is an
> important responsibility, I think this should be emphasized.

I agree that this is important, and should be made clear in any final
proposal.

> On Tue, Mar 12, 2013 at 12:32 PM, Yaron Minsky <yminsky at gmail.com> wrote:
>> I have no objection to specifying that Core#Common should be connected
>> to the Core package within the build system.  But it's important to us
>> that namespace manipulations be observable by the programmer by
>> reading the code.  If I understand correctly, Leo's proposal involves
>> stashing that away in the build system, which undermines that goal.
>>
>> Another thing which may not be obvious is that one sometimes in the
>> same file wants to access just Core.Std in some scopes in the file,
>> and Async.Std in other scopes.  Full control of the namespace is
>> important, and something we do at multiple scopes within a file.
>> Being able to control this only at the file level, and only from
>> within the build system, is a poor match for our needs.
>>
>> The fact that one should write:
>>
>> open Core.Std
>> open Async.Std
>>
>> in a specific order does not strike me as a particular problem, and
>> even if it were, the solution I think would not be to stuff it into
>> the build system, but to build a single namespace that opened both
>> Core and Async.
>>
>> If the proposal lands in the way Leo describes, I would think we would
>> write a ppx extension that, for a certain whitelist of namespaces,
>> would convert:
>>
>>    open namespace Core
>>
>> into
>>
>>    open namespace Core
>>    open Core#Common
>>
>> Given that this is easy enough to do at the ppx level, I find it hard
>> to see what difficulties would be raised by integrating this with the
>> namespace system.  I understand that it feels mildly unsanitary
>> because on the implementation end the two things are quite different,
>> but from a user point of view, I think it's very much the right thing.
>>
>> y
>>
>>
>> On Tue, Mar 12, 2013 at 6:57 AM, Leo White <lpw25 at cam.ac.uk> wrote:
>>>> Leo's model allows the build system to precisely set the order of default
>>>> opens, and tools such as ocamlfind could support this just as they do
>>>> include and link directives at the moment.  I know JS doesn't use
>>>> ocamlfind, but the moral equivalent could inject the command-line
>>>> directives very easily.
>>>
>>> To expand on what Anil said, under my proposed system the idea is to push the
>>> problem of providing "pervasive" modules into the build or package system.
>>>
>>> For example, I would expect Core to provide some kind of package description
>>> for OCamlFind or similar tool including something like (using made up
>>> syntax):
>>>
>>>     path := ./core.mlpath
>>>     open := Core#Common
>>>
>>> where "core.mlpath" is a search path description file.
>>>
>>> Then Async would include a description including something like:
>>>
>>>     path := ./async.mlpath
>>>     path-depends := core
>>>     open := Async#Common
>>>     open-depends := core
>>>
>>> where "async.mlpath" is a search path description file that includes:
>>>
>>>     Core#Original#*: Core#*
>>>     Core#Gc: Async#Gc
>>>     Core#Condition: Async#Condition
>>>
>>> where "Gc" and "Condition" are the components of Core that Async
>>> re-implements.
>>>
>>> This would mean that commands equivalent to any of the following would all
>>> produce the correct default environment for using Async:
>>>
>>>     ocamlc -package async
>>>     ocamlc -package async -package core
>>>     ocamlc -package core -package async
>>>
>>> I think this is preferable to requiring all users of Async to start their
>>> files with:
>>>
>>>     open Core.Std
>>>     open Async.Std
>>>
>>> which is not something that a user might naturally assume was required.
>> _______________________________________________
>> Platform mailing list
>> Platform at lists.ocaml.org
>> http://lists.ocaml.org/listinfo/platform


More information about the Platform mailing list