From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 75A017FB38 for ; Sun, 28 Dec 2014 00:04:15 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of jordojw@gmail.com) identity=pra; client-ip=209.85.215.47; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jordojw@gmail.com"; x-sender="jordojw@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of jordojw@gmail.com designates 209.85.215.47 as permitted sender) identity=mailfrom; client-ip=209.85.215.47; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jordojw@gmail.com"; x-sender="jordojw@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-la0-f47.google.com) identity=helo; client-ip=209.85.215.47; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jordojw@gmail.com"; x-sender="postmaster@mail-la0-f47.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApIAAEc6n1TRVdcvm2dsb2JhbABcg1hYBIMBwXiBYYZ9BxYBAQEBAREBAQEBAQYLCwkULoQlER0BGx4DEhA3AiQBEQEFASIbGod1AQMRn1uDJz4xiy6Ba4J3ijgKGScNVIRbAQUOkliBQQWJS4JzhRaFNIENMIo+ghyBbxIjgQwJhDEdMYJDAQEB X-IPAS-Result: ApIAAEc6n1TRVdcvm2dsb2JhbABcg1hYBIMBwXiBYYZ9BxYBAQEBAREBAQEBAQYLCwkULoQlER0BGx4DEhA3AiQBEQEFASIbGod1AQMRn1uDJz4xiy6Ba4J3ijgKGScNVIRbAQUOkliBQQWJS4JzhRaFNIENMIo+ghyBbxIjgQwJhDEdMYJDAQEB X-IronPort-AV: E=Sophos;i="5.07,653,1413237600"; d="scan'208";a="94813269" Received: from mail-la0-f47.google.com ([209.85.215.47]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 28 Dec 2014 00:04:14 +0100 Received: by mail-la0-f47.google.com with SMTP id hz20so9668884lab.6 for ; Sat, 27 Dec 2014 15:04:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=wyCGV2yq0UAnCiV6YrVRyiI3ZVjHh7IIKwpcd8bm+0I=; b=k6uvP0+p0VyH6UDg7uRkP3QbEE1dqVFF5Zx4idCA2sfACD8EZCCj9KrVT4dU+3dCl4 7J9ZjZ5qdN1eTLb0OSbacKhDqqaF7Gpo8uEBwleamyEtcke6U1YO4+aST6YN1H8UkMEB JGDDcP1ejitwAH2eT0+mxno1dGkE7noCZeLdS5OmoMmtcNTJT8BnGpRwEKdWt7BlpPd8 gY523QjvKh5Lqz/BG4UWsz1CDPYJz9EGdA4+0whOrTku6MJ2TKJcwy5jWlV+/vHjFhFK oDAL/3Bf83joyBsOZ/uUx2VVENTztkl02Sv/wYMj6cWR+MFcf5A6F+kxkND4Y3Mu9FLr F2Bw== MIME-Version: 1.0 X-Received: by 10.152.4.200 with SMTP id m8mr38642199lam.17.1419721453506; Sat, 27 Dec 2014 15:04:13 -0800 (PST) Received: by 10.25.143.207 with HTTP; Sat, 27 Dec 2014 15:04:13 -0800 (PST) Date: Sat, 27 Dec 2014 15:04:13 -0800 Message-ID: From: Jordan W To: "caml-list@inria.fr" Content-Type: multipart/alternative; boundary=089e013d1152ea9811050b3aa85f X-Validation-by: jordojw@gmail.com Subject: [Caml-list] Module aliases ideal name-spacing --089e013d1152ea9811050b3aa85f Content-Type: text/plain; charset=UTF-8 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. --089e013d1152ea9811050b3aa85f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
I'd like to find the best approach to packaging u= p fine grained libraries that can be shared across multiple code bases whil= e avoiding namespace collisions. I found packs to work wonderfully, but hav= e heard that module namespaces have other advantages, so I'm trying to = find the best approach there.

In all of the module alia= ses examples that I've seen, the suggested file/naming structures are a= s follows:

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

- myLibModuleB.ml
=C2=A0 op= en MyLib =C2=A0 =C2=A0(* So that this module can refer to short name Module= A *)

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

<= div>- myLib.mli and myLib.ml
=C2=A0 =C2=A0(* Reexporting short na= mes, mapped to longer internal names *)
=C2=A0 =C2=A0module = ModuleA =3D MyLibModuleA
=C2=A0 =C2=A0module ModuleB = =3D MyLibModuleB


If I underst= and 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 c= ouple of issues with this.
1. When reading my library code, or cl= ient's code, it's not intuitive how to find the source of MyLib.Mod= uleA. Readers must first look at exactly how they've been aliased to fi= nd 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 t= o allow internal modules to have short names, along with those short names = being reflected in short file names? I appreciate the ability to *arbitrari= ly* alias modules with whatever names we wish (so I'm not asking for de= creased flexibility), but it seems critical that two different library auth= ors 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, the= n 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.
---------
<= div>
~/myLib/myModule.ml
=C2=A0 open MyLib= =C2=A0 =C2=A0(* This is not needed - short names are same as long *)
=
=C2=A0 (* Sees Utils belonging to MyLib *)

~/myLib/utils.ml
=C2=A0 open M= yLib =C2=A0 =C2=A0(* This is not needed - short names are same as long *)

~/myLib/myLib.mli and ~/myLib/myLib.ml
<= div>=C2=A0 =C2=A0module MyModule =3D MyModule
=C2=A0 =C2= =A0module Utils =3D Utils


Another set of modules ("project") that depends on th= e previous project YourLib
---------

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

~/yourLib/utils.ml
=C2=A0 open Y= ourLib =C2=A0 =C2=A0(* This is not needed - short names are same as long *)=

~/yourLib/yourLib.mli and ~/yourLib/yourLib= .ml
=C2=A0 =C2=A0module YourModule =3D YourModule
= =C2=A0 =C2=A0module Utils =3D Utils


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

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

Can the first = two "projects" be compiled separately, so that each sees their ow= n copy of the Utils module, then be linked into the final compilation of My= App, 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= 9;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 c= ritical to developing large scale codebases. If not yet possible, is there = a workaround and is it on the roadmap?

Thank you f= or your help.
--089e013d1152ea9811050b3aa85f--