www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - packageless modules == pure evil?

reply Bill Baxter <dnewsgroup billbaxter.com> writes:
I would just like to confirm with others that this is the case, and also 
perhaps raise general awareness about the issue.

The issue is that modules without a package will conflict with a 
similarly named module in _any_ package.

So for example if there's a module called "foo" and you import it in 
your project, then your project absolutely CANNOT have another module 
named "foo" or "blarf.foo" or /anything/ that ends in ".foo" anywhere in 
the import chain.

For this reason it must be concluded that packageless modules are pure 
evil, and should never ever be used.  Always always give your modules a 
package even if it's just repeating the module name like "foo.foo".

Am I right about this?
(and anyone know if module "foo.bar" will clash with "baz.foo"?)

--bb
Feb 17 2008
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bill Baxter:
 For this reason it must be concluded that packageless modules are pure 
 evil, and should never ever be used.  Always always give your modules a 
 package even if it's just repeating the module name like "foo.foo".

If what you say is right, then the solution is to fix the module system of the compiler. It has other "bugs" I have discussed days ago. Bye, bearophile
Feb 17 2008
prev sibling parent reply torhu <no spam.invalid> writes:
Bill Baxter wrote:
 I would just like to confirm with others that this is the case, and also 
 perhaps raise general awareness about the issue.
 
 The issue is that modules without a package will conflict with a 
 similarly named module in _any_ package.
 
 So for example if there's a module called "foo" and you import it in 
 your project, then your project absolutely CANNOT have another module 
 named "foo" or "blarf.foo" or /anything/ that ends in ".foo" anywhere in 
 the import chain.
 
 For this reason it must be concluded that packageless modules are pure 
 evil, and should never ever be used.  Always always give your modules a 
 package even if it's just repeating the module name like "foo.foo".
 
 Am I right about this?

What kind of conflict do you mean? Compiler errors or linker errors? The only linking problem I've seen is that if you have two modules with the same name, the compiler will overwrite one with the other, so only one of them gets linked in. I guess the -op switch to bud or the compiler will fix this. dsss avoids this issue by default, as long as you don't have two modules of the same name and both are packageless. I've come across this issue maybe once, and then I just renamed one of the files to fix it.
 (and anyone know if module "foo.bar" will clash with "baz.foo"?)

Tango has packages and modules with the same name, so it should work.
Feb 17 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
torhu wrote:
 Bill Baxter wrote:
 I would just like to confirm with others that this is the case, and 
 also perhaps raise general awareness about the issue.

 The issue is that modules without a package will conflict with a 
 similarly named module in _any_ package.

 So for example if there's a module called "foo" and you import it in 
 your project, then your project absolutely CANNOT have another module 
 named "foo" or "blarf.foo" or /anything/ that ends in ".foo" anywhere 
 in the import chain.

 For this reason it must be concluded that packageless modules are pure 
 evil, and should never ever be used.  Always always give your modules 
 a package even if it's just repeating the module name like "foo.foo".

 Am I right about this?

What kind of conflict do you mean? Compiler errors or linker errors? The only linking problem I've seen is that if you have two modules with the same name, the compiler will overwrite one with the other, so only one of them gets linked in. I guess the -op switch to bud or the compiler will fix this. dsss avoids this issue by default, as long as you don't have two modules of the same name and both are packageless. I've come across this issue maybe once, and then I just renamed one of the files to fix it.

The problem that prompted this message was that I had a module called just "blas" in one place and was trying to make another module called "dflat.blas". But that breaks plain "import blas". It picks up the "dflat.blas" rather than the packageless blas, even though I didn't specify that I wanted "dflat.blas".
 (and anyone know if module "foo.bar" will clash with "baz.foo"?)

Tango has packages and modules with the same name, so it should work.

But the top-level package may be special. I don't think there's a module called "tango" in Tango, is there? --bb
Feb 17 2008
next sibling parent reply torhu <no spam.invalid> writes:
Bill Baxter wrote:
 The problem that prompted this message was that I had a module called 
 just "blas" in one place and was trying to make another module called 
 "dflat.blas".  But that breaks plain "import blas".  It picks up the 
 "dflat.blas" rather than the packageless blas, even though I didn't 
 specify that I wanted "dflat.blas".

It works when I try a simple test. I have a.d, b/a.d, and then import just 'a' into test.d. a.d: --- module a; char[] s = "a"; --- b/a.d: --- module b.a; char[] s = "b.a"; --- test.d: --- import std.stdio; import a; void main() { writefln(s); } --- running: --- c:\prog\test\D\baxter>bud -exec test a --- So a more complex test is needed to show the problem. Maybe importing from different include paths, etc?
Feb 17 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
torhu wrote:
 Bill Baxter wrote:
 The problem that prompted this message was that I had a module called 
 just "blas" in one place and was trying to make another module called 
 "dflat.blas".  But that breaks plain "import blas".  It picks up the 
 "dflat.blas" rather than the packageless blas, even though I didn't 
 specify that I wanted "dflat.blas".

It works when I try a simple test. I have a.d, b/a.d, and then import just 'a' into test.d. a.d: --- module a; char[] s = "a"; --- b/a.d: --- module b.a; char[] s = "b.a"; --- test.d: --- import std.stdio; import a; void main() { writefln(s); } --- running: --- c:\prog\test\D\baxter>bud -exec test a --- So a more complex test is needed to show the problem. Maybe importing from different include paths, etc?

Ok, thanks for helping me to work through this, torhu. There may not be any pure evil going on here. In trying to make a simple repro I've found that if I get rid of the top level a.d (or move it into a different subdir without using a -I to find it), I get the highly misleading error message: "b\c.d(4): module b.a is in multiple packages b.a" So this could be the root of the problem. I think that was the error I was seeing previously that made me thing it was mixing up the two modules. I'll dig in a little more and report what I find. --bb
Feb 17 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Bill Baxter wrote:
 torhu wrote:
 Bill Baxter wrote:
 The problem that prompted this message was that I had a module called 
 just "blas" in one place and was trying to make another module called 
 "dflat.blas".  But that breaks plain "import blas".  It picks up the 
 "dflat.blas" rather than the packageless blas, even though I didn't 
 specify that I wanted "dflat.blas".

It works when I try a simple test. I have a.d, b/a.d, and then import just 'a' into test.d. a.d: --- module a; char[] s = "a"; --- b/a.d: --- module b.a; char[] s = "b.a"; --- test.d: --- import std.stdio; import a; void main() { writefln(s); } --- running: --- c:\prog\test\D\baxter>bud -exec test a --- So a more complex test is needed to show the problem. Maybe importing from different include paths, etc?

Ok, thanks for helping me to work through this, torhu. There may not be any pure evil going on here. In trying to make a simple repro I've found that if I get rid of the top level a.d (or move it into a different subdir without using a -I to find it), I get the highly misleading error message: "b\c.d(4): module b.a is in multiple packages b.a" So this could be the root of the problem. I think that was the error I was seeing previously that made me thing it was mixing up the two modules. I'll dig in a little more and report what I find. --bb

Here's a version that causes the problem. It actually seems to be an issue with build tools rather than DMD itself. If you put 'test' inside 'b' and then try to build from there with the -I.. flag, the build tools get confused over the two different a.d files. It seems both bud and dsss get confused about this situation and end up only using one of the a's. What's interesting is the failure modes are quite different. Attached is a zip with the setup.
 cd packageless\b
 bud -full testit

Gives error: --> testit.d(4): module b.a is in multiple packages b.a
 cd packageless\b
 dsss build testit
 testit

Builds fine, but outputs "b.a" instead of "a". This is what I was seeing -- the wrong module gets imported (b.a instead of a). The problem goes away if you build from the 'packageless' dir one level up instead:
 cd packageless
 bud -full b\testit
 testit

Prints "a" as expected. So the final moral of the story is either: 1) don't put test programs in the same directory as package. -or at least- 2) don't build test programs from inside the package directory. --bb
Feb 17 2008
parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Mon, 18 Feb 2008 12:40:02 +0900, Bill Baxter wrote:

 Here's a version that causes the problem.  It actually seems to be an 
 issue with build tools rather than DMD itself.

I'm using BUD v3.05 and I can't get it to go wrong. It works as expected in all four conditions. PWD = packageless bud testitok bud b\testit PWD = packageless\b bud ..\testitok bud testit So I'm not sure what to do to help. -- Derek (skype: derek.j.parnell) Melbourne, Australia 18/02/2008 3:10:26 PM
Feb 17 2008
parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Mon, 18 Feb 2008 15:13:44 +1100, Derek Parnell wrote:

 On Mon, 18 Feb 2008 12:40:02 +0900, Bill Baxter wrote:
 
 Here's a version that causes the problem.  It actually seems to be an 
 issue with build tools rather than DMD itself.

I'm using BUD v3.05 and I can't get it to go wrong. It works as expected in all four conditions. PWD = packageless bud testitok bud b\testit PWD = packageless\b bud ..\testitok bud testit So I'm not sure what to do to help.

<DUH manifestation="slaps forehead"> Oh I know what I can do ... release the version of Bud I'm using to the community.</DUH> -- Derek (skype: derek.j.parnell) Melbourne, Australia 18/02/2008 3:22:50 PM
Feb 17 2008
next sibling parent torhu <no spam.invalid> writes:
Derek Parnell wrote:
 <DUH manifestation="slaps forehead"> Oh I know what I can do ... release
 the version of Bud I'm using to the community.</DUH>

Yes, please. :)
Feb 17 2008
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Derek Parnell wrote:
 On Mon, 18 Feb 2008 15:13:44 +1100, Derek Parnell wrote:
 
 On Mon, 18 Feb 2008 12:40:02 +0900, Bill Baxter wrote:

 Here's a version that causes the problem.  It actually seems to be an 
 issue with build tools rather than DMD itself.

all four conditions. PWD = packageless bud testitok bud b\testit PWD = packageless\b bud ..\testitok bud testit So I'm not sure what to do to help.

<DUH manifestation="slaps forehead"> Oh I know what I can do ... release the version of Bud I'm using to the community.</DUH>

That would be great! I know I've been eagerly waiting for the environment variable support that you've supposedly had implemented for about a year now. --bb
Feb 18 2008
parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 19 Feb 2008 10:05:38 +0900, Bill Baxter wrote:

 Derek Parnell wrote:
 On Mon, 18 Feb 2008 15:13:44 +1100, Derek Parnell wrote:
 
 On Mon, 18 Feb 2008 12:40:02 +0900, Bill Baxter wrote:

 Here's a version that causes the problem.  It actually seems to be an 
 issue with build tools rather than DMD itself.

all four conditions. PWD = packageless bud testitok bud b\testit PWD = packageless\b bud ..\testitok bud testit So I'm not sure what to do to help.

<DUH manifestation="slaps forehead"> Oh I know what I can do ... release the version of Bud I'm using to the community.</DUH>

That would be great! I know I've been eagerly waiting for the environment variable support that you've supposedly had implemented for about a year now.

Oh yeah ... I did do that. It now has a function called 'ExpandEnvVar'. /* Function to replace tokens in the form ... %ENVNAME% $ENVNAME ( Terminated by a non-alpha character ) ${ENVNAME} $(ENVNAME) with environment data. Notes: (1) '%%' is replaced by a single '%' (2) '$$' is replaced by a single '$' (3) The forms $(...) and ${...} can be nested. eg. ${FOO${BAR}} - If 'BAR' is defined as "test" then this tries to find out what 'FOOtest' is defined as. (4) The forms $(...) and ${...} can optionally have default values. eg. $(FOO=yes) - if 'FOO' not defined it is expanded to 'yes' $(BAR=${QWERTY}} - if 'BAR' not defined it is expanded to whatever 'QWERTY' is defined as. (5) The form $(...) is expanded recursively. e.g. $(FOO) - if 'FOO' is defined as "${BAR}" then the result is returned as whatever 'BAR' is defined as. */ -- Derek (skype: derek.j.parnell) Melbourne, Australia 19/02/2008 12:25:10 PM
Feb 18 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Derek Parnell wrote:
 On Tue, 19 Feb 2008 10:05:38 +0900, Bill Baxter wrote:
 
 Derek Parnell wrote:
 On Mon, 18 Feb 2008 15:13:44 +1100, Derek Parnell wrote:

 On Mon, 18 Feb 2008 12:40:02 +0900, Bill Baxter wrote:

 Here's a version that causes the problem.  It actually seems to be an 
 issue with build tools rather than DMD itself.

all four conditions. PWD = packageless bud testitok bud b\testit PWD = packageless\b bud ..\testitok bud testit So I'm not sure what to do to help.

the version of Bud I'm using to the community.</DUH>

environment variable support that you've supposedly had implemented for about a year now.

Oh yeah ... I did do that. It now has a function called 'ExpandEnvVar'. /* Function to replace tokens in the form ... %ENVNAME% $ENVNAME ( Terminated by a non-alpha character ) ${ENVNAME} $(ENVNAME) with environment data. Notes: (1) '%%' is replaced by a single '%' (2) '$$' is replaced by a single '$' (3) The forms $(...) and ${...} can be nested. eg. ${FOO${BAR}} - If 'BAR' is defined as "test" then this tries to find out what 'FOOtest' is defined as. (4) The forms $(...) and ${...} can optionally have default values. eg. $(FOO=yes) - if 'FOO' not defined it is expanded to 'yes' $(BAR=${QWERTY}} - if 'BAR' not defined it is expanded to whatever 'QWERTY' is defined as. (5) The form $(...) is expanded recursively. e.g. $(FOO) - if 'FOO' is defined as "${BAR}" then the result is returned as whatever 'BAR' is defined as. */

Sweet! Now just release that puppy, already! Or stop teasing us with descriptions of functionality we can't have. :-P --bb
Feb 18 2008
parent Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 19 Feb 2008 10:41:53 +0900, Bill Baxter wrote:

 Now just release that puppy, already!  Or stop teasing us with 
 descriptions of functionality we can't have. :-P

I'm at the office right now but the master source is back at home, so I'll get onto tonight after work. As I remember, it wasn't too happy with the latest DMD2 compiler ... but I can do without sleep to fix that ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia 19/02/2008 1:59:10 PM
Feb 18 2008
prev sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
This is because you are adding all directories to the import path 
perhaps?  For example if you do -I. -Iflat then you might have this problem.

-[Unknown]


Bill Baxter wrote:
 torhu wrote:
 Bill Baxter wrote:
 I would just like to confirm with others that this is the case, and 
 also perhaps raise general awareness about the issue.

 The issue is that modules without a package will conflict with a 
 similarly named module in _any_ package.

 So for example if there's a module called "foo" and you import it in 
 your project, then your project absolutely CANNOT have another module 
 named "foo" or "blarf.foo" or /anything/ that ends in ".foo" anywhere 
 in the import chain.

 For this reason it must be concluded that packageless modules are 
 pure evil, and should never ever be used.  Always always give your 
 modules a package even if it's just repeating the module name like 
 "foo.foo".

 Am I right about this?

What kind of conflict do you mean? Compiler errors or linker errors? The only linking problem I've seen is that if you have two modules with the same name, the compiler will overwrite one with the other, so only one of them gets linked in. I guess the -op switch to bud or the compiler will fix this. dsss avoids this issue by default, as long as you don't have two modules of the same name and both are packageless. I've come across this issue maybe once, and then I just renamed one of the files to fix it.

The problem that prompted this message was that I had a module called just "blas" in one place and was trying to make another module called "dflat.blas". But that breaks plain "import blas". It picks up the "dflat.blas" rather than the packageless blas, even though I didn't specify that I wanted "dflat.blas".
 (and anyone know if module "foo.bar" will clash with "baz.foo"?)

Tango has packages and modules with the same name, so it should work.

But the top-level package may be special. I don't think there's a module called "tango" in Tango, is there? --bb

Feb 17 2008