caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Module aliases ideal name-spacing
@ 2014-12-27 23:04 Jordan W
  2014-12-28 18:15 ` Leo White
  0 siblings, 1 reply; 7+ messages in thread
From: Jordan W @ 2014-12-27 23:04 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 3831 bytes --]

I'd like to find the best approach to packaging up fine grained libraries
that can be shared across multiple code bases while avoiding namespace
collisions. I found packs to work wonderfully, but have heard that module
namespaces have other advantages, so I'm trying to find the best approach
there.

In all of the module aliases examples that I've seen, the suggested
file/naming structures are as follows:

- myLibModuleA.ml
  open MyLib    (* So that this module can refer to short name ModuleB *)

- myLibModuleB.ml
  open MyLib    (* So that this module can refer to short name ModuleA *)

- Optionally, we can have the compiler automatically open `MyLib` in the
previous two files.

- myLib.mli and myLib.ml
   (* Reexporting short names, mapped to longer internal names *)
   module ModuleA = MyLibModuleA
   module ModuleB = MyLibModuleB


If I understand correctly, module naming conflicts are avoided because
`myLibModuleA.ml` implicitly generates a module name of `MyLibModuleA`
which is unlikely to collide with any other module written by another
developer that I compile along with - because the file name was prefixed
with something sufficiently unique. Then, users of exported modules are
encouraged to access them via `MyLib.ModuleA/B`.

But there still seems to be a couple of issues with this.
1. When reading my library code, or client's code, it's not intuitive how
to find the source of MyLib.ModuleA. Readers must first look at exactly how
they've been aliased to find the long name.
2. People may not want to prefix their internal modules, especially since
they're going through the trouble of making a mapping anyways.


Is there a way to allow internal modules to have short names, along with
those short names being reflected in short file names? I appreciate the
ability to *arbitrarily* alias modules with whatever names we wish (so I'm
not asking for decreased flexibility), but it seems critical that two
different library authors be able to have their own internal module named
`Utils` in a file named `utils.ml`. Packs allow this, and it seems if
module aliases are being encouraged as the proper way to namespace, then
they should be capable of namespacing properly. Is the following possible
with module aliases?

One set of modules that form a kind of namespaced "project" MyLib.
---------

~/myLib/myModule.ml
  open MyLib    (* This is not needed - short names are same as long *)
  (* Sees Utils belonging to MyLib *)

~/myLib/utils.ml
  open MyLib    (* This is not needed - short names are same as long *)

~/myLib/myLib.mli and ~/myLib/myLib.ml
   module MyModule = MyModule
   module Utils = Utils


Another set of modules ("project") that depends on the previous project
YourLib
---------

~/yourLib/yourModule.ml
  open YourLib    (* This is not needed - short names are same as long *)
  (* Sees Utils belonging to YourLib *)

~/yourLib/utils.ml
  open YourLib    (* This is not needed - short names are same as long *)

~/yourLib/yourLib.mli and ~/yourLib/yourLib.ml
   module YourModule = YourModule
   module Utils = Utils


Finally, an application "project" that uses the namespaces generated by the
previous two projects
---------

~/myApp/myApp.ml
let x = MyLib.Utils.x + YourLib.Utils.y

Can the first two "projects" be compiled separately, so that each sees
their own copy of the Utils module, then be linked into the final
compilation of MyApp, with namespaces properly in place? I am able to do
this with packs. If possible with module aliases, is there an example of
doing so? I couldn't find this fact confirmed/denied in the Type Level
Module Aliases paper and I expected it to be addressed because being able
to do this is fairly critical to developing large scale codebases. If not
yet possible, is there a workaround and is it on the roadmap?

Thank you for your help.

[-- Attachment #2: Type: text/html, Size: 4966 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Module aliases ideal name-spacing
  2014-12-27 23:04 [Caml-list] Module aliases ideal name-spacing Jordan W
@ 2014-12-28 18:15 ` Leo White
  2014-12-28 20:34   ` Jordo
  0 siblings, 1 reply; 7+ messages in thread
From: Leo White @ 2014-12-28 18:15 UTC (permalink / raw)
  To: Jordan W; +Cc: caml-list

> One set of modules that form a kind of namespaced "project" MyLib.
> ---------
>
> ~/myLib/myModule.ml
>   open MyLib    (* This is not needed - short names are same as long *)
>   (* Sees Utils belonging to MyLib *)
>
> ~/myLib/utils.ml
>   open MyLib    (* This is not needed - short names are same as long *)
>
> ~/myLib/myLib.mli and ~/myLib/myLib.ml
>    module MyModule = MyModule
>    module Utils = Utils
>
> Another set of modules ("project") that depends on the previous project YourLib
> ---------
>
> ~/yourLib/yourModule.ml
>   open YourLib    (* This is not needed - short names are same as long *)
>   (* Sees Utils belonging to YourLib *)
>
> ~/yourLib/utils.ml
>   open YourLib    (* This is not needed - short names are same as long *)
>
> ~/yourLib/yourLib.mli and ~/yourLib/yourLib.ml
>    module YourModule = YourModule
>    module Utils = Utils
>
> Finally, an application "project" that uses the namespaces generated by the previous two projects
> ---------
>
> ~/myApp/myApp.ml
> let x = MyLib.Utils.x + YourLib.Utils.y
>

You can use the `-o` and `-open` command-line options to get the
behaviour you are after. If you change myLib/myLib.ml(i) to be

    module MyModule = MyLibMyModule
    module Utils = MyLibUtils

and make similar changes to yourLib/yourLib.ml(i), then you can use the
following commands:

    cd ~/myLib
    ocamlc -no-alias-deps myLib.mli
    ocamlc -no-alias-deps myLib.ml
    ocamlc -c -open MyLib -o myLibUtils.cmo utils.ml
    ocamlc -c -open MyLib -o myLibMyModule.cmo myModule.ml

    cd ~/yourLib
    ocamlc -c -no-alias-deps yourLib.mli
    ocamlc -c -no-alias-deps yourLib.ml
    ocamlc -c -open YourLib -o yourLibUtils.cmo utils.ml
    ocamlc -c -open YourLib -o yourLibYourModule.cmo yourModule.ml

    cd ~/myApp
    ocamlc -c -I ../myLib -I ../yourLib myApp.ml

Setting up this compilation scheme in your build system might be a bit
of effort, but it should work.

Regards,

Leo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Module aliases ideal name-spacing
  2014-12-28 18:15 ` Leo White
@ 2014-12-28 20:34   ` Jordo
  2014-12-28 21:26     ` Leo White
  0 siblings, 1 reply; 7+ messages in thread
From: Jordo @ 2014-12-28 20:34 UTC (permalink / raw)
  To: Leo White; +Cc: caml-list

Thank you for the reply, Leo. One of the requirements was that developers be able to name their internal modules as they see fit without having to fear naming collisions. It's also required that file names correspond directly to module names (or at least we retain the capability to do so). It appears in this solution you suggested, developers still must prefix their file names in order to avoid collisions. That is unintuitive because it's not always clear why a file is named differently than its namespaced alias. Readers must examine the module alias file to know which file a module is implemented in. Packs provided a solution to this and I'm hoping we may continue that highly effective pattern while also enjoying the benefits of module aliases. Having the freedom to name modules without fear of collision outside of your "project" seems strictly better than having to be concerned about collisions outside of your project. Is there any sequence of compilation commands that will guard these namespaces as I've been successfully doing with packs? Could the proper solution be to actually have packs use module aliases? That might allow *proper* namespacing along with the compilation benefits of aliases. Is there any other way?

I


On Dec 28, 2014, at 10:15 AM, Leo White <lpw25@cam.ac.uk> wrote:

>> One set of modules that form a kind of namespaced "project" MyLib.
>> ---------
>> 
>> ~/myLib/myModule.ml
>>   open MyLib    (* This is not needed - short names are same as long *)
>>   (* Sees Utils belonging to MyLib *)
>> 
>> ~/myLib/utils.ml
>>   open MyLib    (* This is not needed - short names are same as long *)
>> 
>> ~/myLib/myLib.mli and ~/myLib/myLib.ml
>>    module MyModule = MyModule
>>    module Utils = Utils
>> 
>> Another set of modules ("project") that depends on the previous project YourLib
>> ---------
>> 
>> ~/yourLib/yourModule.ml
>>   open YourLib    (* This is not needed - short names are same as long *)
>>   (* Sees Utils belonging to YourLib *)
>> 
>> ~/yourLib/utils.ml
>>   open YourLib    (* This is not needed - short names are same as long *)
>> 
>> ~/yourLib/yourLib.mli and ~/yourLib/yourLib.ml
>>    module YourModule = YourModule
>>    module Utils = Utils
>> 
>> Finally, an application "project" that uses the namespaces generated by the previous two projects
>> ---------
>> 
>> ~/myApp/myApp.ml
>> let x = MyLib.Utils.x + YourLib.Utils.y
> 
> You can use the `-o` and `-open` command-line options to get the
> behaviour you are after. If you change myLib/myLib.ml(i) to be
> 
>    module MyModule = MyLibMyModule
>    module Utils = MyLibUtils
> 
> and make similar changes to yourLib/yourLib.ml(i), then you can use the
> following commands:
> 
>    cd ~/myLib
>    ocamlc -no-alias-deps myLib.mli
>    ocamlc -no-alias-deps myLib.ml
>    ocamlc -c -open MyLib -o myLibUtils.cmo utils.ml
>    ocamlc -c -open MyLib -o myLibMyModule.cmo myModule.ml
> 
>    cd ~/yourLib
>    ocamlc -c -no-alias-deps yourLib.mli
>    ocamlc -c -no-alias-deps yourLib.ml
>    ocamlc -c -open YourLib -o yourLibUtils.cmo utils.ml
>    ocamlc -c -open YourLib -o yourLibYourModule.cmo yourModule.ml
> 
>    cd ~/myApp
>    ocamlc -c -I ../myLib -I ../yourLib myApp.ml
> 
> Setting up this compilation scheme in your build system might be a bit
> of effort, but it should work.
> 
> Regards,
> 
> Leo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Module aliases ideal name-spacing
  2014-12-28 20:34   ` Jordo
@ 2014-12-28 21:26     ` Leo White
  2014-12-28 23:25       ` Jordan W
  0 siblings, 1 reply; 7+ messages in thread
From: Leo White @ 2014-12-28 21:26 UTC (permalink / raw)
  To: Jordo; +Cc: caml-list

Jordo <jordojw@gmail.com> writes:

> Thank you for the reply, Leo. One of the requirements was that developers be able to name their internal modules as they
> see fit without having to fear naming collisions. It's also required that file names correspond directly to module names
> (or at least we retain the capability to do so). It appears in this solution you suggested, developers still must prefix
> their file names in order to avoid collisions.

None of the source files have prefixed names, only intermediate files
(that is why you use `-o`). For both reading the source code and using
the library through `MyLib.Foo`, the prefix does not appear.

Regards,

Leo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Module aliases ideal name-spacing
  2014-12-28 21:26     ` Leo White
@ 2014-12-28 23:25       ` Jordan W
  2014-12-29  0:14         ` Leo White
  0 siblings, 1 reply; 7+ messages in thread
From: Jordan W @ 2014-12-28 23:25 UTC (permalink / raw)
  To: Leo White; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1478 bytes --]

Oh, I missed that detail. That actually could work quite nicely. Though
it's a bit of a messy build script, it's something we could write
generically to work well on any "project". The only remaining remnant of
the "prefixed" namespace is in myLib.mli/.ml


    module MyModule = MyLibMyModule
    module Utils = MyLibUtils

It would be nice to eliminate that as well, but I could imagine
auto-generating these module alias mappings. This sounds like a nice
workaround the namespace issue, but do you think it would be worth
supporting module aliases themselves as a form of namespacing at
compilation time, so that this intermediate prefixed compilation artifact
isn't needed?

Thank you for the help,
J

On Sun, Dec 28, 2014 at 1:26 PM, Leo White <lpw25@cam.ac.uk> wrote:

> Jordo <jordojw@gmail.com> writes:
>
> > Thank you for the reply, Leo. One of the requirements was that
> developers be able to name their internal modules as they
> > see fit without having to fear naming collisions. It's also required
> that file names correspond directly to module names
> > (or at least we retain the capability to do so). It appears in this
> solution you suggested, developers still must prefix
> > their file names in order to avoid collisions.
>
> None of the source files have prefixed names, only intermediate files
> (that is why you use `-o`). For both reading the source code and using
> the library through `MyLib.Foo`, the prefix does not appear.
>
> Regards,
>
> Leo
>

[-- Attachment #2: Type: text/html, Size: 2189 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Module aliases ideal name-spacing
  2014-12-28 23:25       ` Jordan W
@ 2014-12-29  0:14         ` Leo White
  2015-01-07 15:15           ` Goswin von Brederlow
  0 siblings, 1 reply; 7+ messages in thread
From: Leo White @ 2014-12-29  0:14 UTC (permalink / raw)
  To: Jordan W; +Cc: caml-list

> The only remaining remnant of the "prefixed"
> namespace is in myLib.mli/.ml
>
>
>     module MyModule = MyLibMyModule
>     module Utils = MyLibUtils
>
> It would be nice to eliminate that as well, but I could imagine
> auto-generating these module alias mappings.

It is certainly feasible to have the build system generate these
mappings automatically. For example, I believe that Jane Street's
example build rules for Jenga include support for generating these alias
mappings (examples/js-build-style/jengaroot.ml in the Jenga source
code).

> This
> sounds like a nice workaround the namespace issue, but do you think it would be worth supporting module aliases
> themselves as a form of namespacing at compilation time, so that this intermediate prefixed compilation artifact isn't
> needed?

I'm aware of a few proposals, and I'm sure something more user-friendly
will happen at some point, but the details of these proposals are tricky
and important to get right. For now, the support in 4.02 is at least
sufficient to have a working replacement for `-pack`.

Regards,

Leo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Module aliases ideal name-spacing
  2014-12-29  0:14         ` Leo White
@ 2015-01-07 15:15           ` Goswin von Brederlow
  0 siblings, 0 replies; 7+ messages in thread
From: Goswin von Brederlow @ 2015-01-07 15:15 UTC (permalink / raw)
  To: caml-list

On Mon, Dec 29, 2014 at 12:14:58AM +0000, Leo White wrote:
> > The only remaining remnant of the "prefixed"
> > namespace is in myLib.mli/.ml
> >
> >
> >     module MyModule = MyLibMyModule
> >     module Utils = MyLibUtils
> >
> > It would be nice to eliminate that as well, but I could imagine
> > auto-generating these module alias mappings.
> 
> It is certainly feasible to have the build system generate these
> mappings automatically. For example, I believe that Jane Street's
> example build rules for Jenga include support for generating these alias
> mappings (examples/js-build-style/jengaroot.ml in the Jenga source
> code).
> 
> > This
> > sounds like a nice workaround the namespace issue, but do you think it would be worth supporting module aliases
> > themselves as a form of namespacing at compilation time, so that this intermediate prefixed compilation artifact isn't
> > needed?
> 
> I'm aware of a few proposals, and I'm sure something more user-friendly
> will happen at some point, but the details of these proposals are tricky
> and important to get right. For now, the support in 4.02 is at least
> sufficient to have a working replacement for `-pack`.
> 
> Regards,
> 
> Leo

Isn't this just an improvement on pack to reduce code size? As in
sources that only use MyLib.Util will only get MyLibUtil linked in but
not MyLibMyModule.

From a user standpoint a MyLib pack or the MyLib aliases should be the
same. So maybe the build system could use pack for old ocaml and alias
for new ocaml. Packs would work as is and for aliases the build system
would generate the myLib.ml(i) automatically.

Should be fairly easy to do in _oasis, I hope.

MfG
	Goswin

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-01-07 15:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-27 23:04 [Caml-list] Module aliases ideal name-spacing Jordan W
2014-12-28 18:15 ` Leo White
2014-12-28 20:34   ` Jordo
2014-12-28 21:26     ` Leo White
2014-12-28 23:25       ` Jordan W
2014-12-29  0:14         ` Leo White
2015-01-07 15:15           ` Goswin von Brederlow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).