Namespace for a module defined by its import path

Jonathan Marler via Digitalmars-d digitalmars-d at puremagic.com
Wed Oct 26 10:12:30 PDT 2016


On Wednesday, 26 October 2016 at 09:53:35 UTC, Jeff Thompson 
wrote:
> On Wednesday, 26 October 2016 at 07:57:57 UTC, Mike Parker 
> wrote:
>> On Wednesday, 26 October 2016 at 07:14:30 UTC, Jeff Thompson 
>> wrote:
>>
>>>>
>>>> dmd 
>>>> -I/commit_b3bf5c7725c98ee3e49dfc4e47318162f138fe94/version/ 
>>>> main.d
>>>> dmd 
>>>> -I//commit_df0741a84c8a967ea08674090afdff4e9a58d23e/version/ 
>>>> main.d
>>>
>>> This will force the application to use either one version or 
>>> the other. As I said, it's a large application. I different 
>>> parts of the same application to be able to import the 
>>> version they need.
>>
>> A module named foo.bar is foo.bar. There's no way to have a 
>> foo.bar version1 and a foo.bar version2 in the same program. 
>> You compile and link one version or the other, period. If you 
>> want multiple versions in the same program, then they need to 
>> have distinct module names:
>>
>> foo/bar1.d --> module foo.bar1;
>> foo/bar2.d --> module foo.bar2;
>>
>> I can't see how you would expect it to work otherwise. How 
>> would the compiler know that a call to foo.bar.someFunc 
>> belongs to one version or another if both have the same fully 
>> qualified name?
>>
>> Or maybe I'm misunderstanding you (and I'm apparently not the 
>> only one in this thread). What problem are you trying to 
>> solve? Why do you need different versions of the same module 
>> or package at the same time in the same program?
>
> I need different versions of the same module at the same time 
> in the same program to be able to use multiple libraries, some 
> of which have been verified to work one version of the module 
> and others to work with another version. It is to be able to 
> have reliability in large scale programs where different 
> libraries have slightly different dependencies.
>
> I can do this in Node.js. Suppose I have the following files:
>
> commit_b3bf5c7/utils.js
> commit_df0741a/utils.js
> somelib.js
> anotherlib.js
>
> In Node.js, somelib.js can have
>
> var Utils = require('commit_b3bf5c7/utils.js').Utils;
>
> And anotherlib.js can have
>
> var Utils = require('commit_df0741a/utils.js').Utils;
>
> with no conflict whatsoever. Each lib can use the version that 
> it knows works correctly.  A file can even include both if it 
> needs to:
>
> var Utils1 = require('commit_b3bf5c7/utils.js').Utils;
> var Utils2 = require('commit_df0741a/utils.js').Utils;
>
> Again no conflict between using Utils1 and Utils2. The point is 
> that the namespace of the identifiers of imported files is 
> defined by the file that imports it. This allows much more 
> scalability, instead of forcing every library and every library 
> it depends on to use the same version of an imported file.

I've thought about this and have concluded that you can't 
replicate these semantics in D.  Here's 2 solutions though:

1. Change the module name for each version ("module 
commit_b3bf5c7.util;").
    CON: when someone uses the util library in isolation, this 
will be odd.

2. If you know that you will only ever use 1 version of the 
library in each file, you can omit the module name in the library 
and import it with the version:
    "import commit_b3bf5c7.util;"
    However, this actual module name will be "util", so if you 
import more than one version in the same file, you will have a 
module name conflict because both will be named "util".  You 
could also use "import util" and select which version to use 
based on the import paths that are passed to the compiler.

Both of these scenarios have caveats (won't work the same as the 
NodeJS version in every case).  To support the NodeJS semantics, 
we would have to modify how modules work a little bit.

If I were to come up with a way to modify the module system to 
support this, I could imagine something like this:

pathimport <path> <module>;

Then the module system would keep track of the path that a module 
was imported by.  So you could do this:

pathimport commit_b3bfc70 util;
pathimport commit_df0741a util;

This would maintain the module name as "util" and also give the 
compiler something to differentiate modules with the same name 
(the path).  I believe if a feature like this was supported, you 
could replicate the same semantics you have in NodeJS, but alas, 
it doesn't exist.  There's probably also a better solution than 
this, but I figured I would try to show you what a potential 
solution looks like so you can understand what's missing.




More information about the Digitalmars-d mailing list