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