www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Import conflict resoultion

reply "Regan Heath" <regan netwin.co.nz> writes:
Here is my current understanding of the problems and solutions proposed to  
date. Comments are welcome, including "enough already! the horse is dead!"  
;)

Regan


Import conflict resolution
--------------------------

Assumptions
-----------
Imports are private by default (Walter seems to like this now?)


Terminology
-----------
FQN = Fully Qualified Name


Problems
--------
A:
Importing 2 modules with the same symbol causes an immediate collision eg.
import std.string;
import std.regexp;

..find(.. //error std.string.find or std.regexp.find

B:
Changes to a module at a later date may cause a collision at a later date.
import a;
import b;

..foo(.. //calling a.foo.

At later date symbol 'foo' is added to b and now the collision occurs.


Current behaviour
-----------------
"How imports work is that first a name is searched for in the current  
namespace. If it is not found, then it is looked for in the import list.  
If it is
found uniquely among the imports, then that is used. If it is in more than  
one import, an error occurs"
  - Walter

"Import does not import names into the current namespace. It imports them  
into a secondary namespace, that is looked in *only* if the name isn't
found in the current namespace. Alias can then cherry-pick specific  
symbols out of that secondary namespace and put them in the current  
namespace,
possibly renaming them along the way."
  - Walter


Current solutions
-----------------
1:
import std.string;
import std.regexp;
alias std.string.find find;

..find(.. //no error std.string.find is called

2:
import std.string;
import std.regexp;

..std.string.find(.. //no error FQN is used


Opinions/pros/cons on the current solutions
-------------------------------------------

1:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
  - CON,The alias is 'physically' seperate from the import.

2:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
  - CON,Causes more verbose code.

Neither of these current solutions solves B.


Proposed solutions
------------------
3:
Prevent import into the "secondary namespace", only allow FQN access. (AKA  
"static import")
static import std.string; //exact syntax may vary
static import std.regexp; //exact syntax may vary

..find(.. //error
..std.string.find(.. //ok
..std.regexp.find(.. //ok

"All 'static import' does is eliminate the "if the name is not found in  
the current module, look in the imports" step. This has the effect of
requiring the use of FQN's when referencing imports."
  - Walter

4:
Import into a custom namespace, eg.
import std.string str; //exact syntax may vary
import std.regexp;

..str.find(.. //calls std.string.find
..find(.. //calls std.regexp.find

This method should also prevent import into the "secondary namespace".

5:
Allow selective import of the exact symbol which is required.
import std.string.find; //exact syntax may vary

..find(.. //calls std.string.find

No symbols from std.string would be present in the "secondary namespace".


Opinions/pros/cons on the various solutions
-------------------------------------------

3:
  - PRO,Solves the import conflict for the intended symbol.
  - PRO,Solves future symbol conflicts in the same module(s).
  - CON,Causes more verbose code, using FQN all the time.

4:
  - PRO,Solves the import conflict for the intended symbol.
  - PRO,Solves future symbol conflicts in the same module(s).

5:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.


Conclusions, extra thoughts
---------------------------

The ideal solution IMO is #4, it solves both A and B in a simple, easy and  
elegant(IMO) fashion something that cannot
be said about the existing solutions #1 and #2.

To the people who want FQN all the time.. You may view the proposed  
solutions #3 and #4 as identical (in value to you).
The deciding factor to my mind is that other people do not want to use FQN  
all the time therefore #4 makes the most
people happy. The interesting thing, is that FQN can be achieved with  
soltion #4, note that:
   import std.string std.string;

would be FQN access, without! any further special syntax (like "static"),  
to me this makes #4 better than #3
even if you want to use FQN.

Yes, it requires more typing but I don't think you can complain about  
having to type the module name once more
when you plan to type it 20+ more times in the course of the file, can you?

FQN access is curently always present, but not required. However, with  
solution #4 FQN access to the symbol is no longer
ever required. It's presence results in code which can call the same  
function in more than one way. This allows the code to
be inconsistent for no gain (that I can imagine) therefore i think that  
solution #4 should prevent FQN access to symbols.
Jul 12 2006
next sibling parent reply Jeremy <Jeremy_member pathlink.com> writes:
In article <optcludog823k2f5 nrage>, Regan Heath says...
Here is my current understanding of the problems and solutions proposed to  
date. Comments are welcome, including "enough already! the horse is dead!"  
;)

Regan


Import conflict resolution
--------------------------

Assumptions
-----------
Imports are private by default (Walter seems to like this now?)


Terminology
-----------
FQN = Fully Qualified Name


Problems
--------
A:
Importing 2 modules with the same symbol causes an immediate collision eg.
import std.string;
import std.regexp;

..find(.. //error std.string.find or std.regexp.find

B:
Changes to a module at a later date may cause a collision at a later date.
import a;
import b;

..foo(.. //calling a.foo.

At later date symbol 'foo' is added to b and now the collision occurs.


Current behaviour
-----------------
"How imports work is that first a name is searched for in the current  
namespace. If it is not found, then it is looked for in the import list.  
If it is
found uniquely among the imports, then that is used. If it is in more than  
one import, an error occurs"
  - Walter

"Import does not import names into the current namespace. It imports them  
into a secondary namespace, that is looked in *only* if the name isn't
found in the current namespace. Alias can then cherry-pick specific  
symbols out of that secondary namespace and put them in the current  
namespace,
possibly renaming them along the way."
  - Walter


Current solutions
-----------------
1:
import std.string;
import std.regexp;
alias std.string.find find;

..find(.. //no error std.string.find is called

2:
import std.string;
import std.regexp;

..std.string.find(.. //no error FQN is used


Opinions/pros/cons on the current solutions
-------------------------------------------

1:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
  - CON,The alias is 'physically' seperate from the import.

2:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
  - CON,Causes more verbose code.

Neither of these current solutions solves B.


Proposed solutions
------------------
3:
Prevent import into the "secondary namespace", only allow FQN access. (AKA  
"static import")
static import std.string; //exact syntax may vary
static import std.regexp; //exact syntax may vary

..find(.. //error
..std.string.find(.. //ok
..std.regexp.find(.. //ok

"All 'static import' does is eliminate the "if the name is not found in  
the current module, look in the imports" step. This has the effect of
requiring the use of FQN's when referencing imports."
  - Walter

4:
Import into a custom namespace, eg.
import std.string str; //exact syntax may vary
import std.regexp;

..str.find(.. //calls std.string.find
..find(.. //calls std.regexp.find

This method should also prevent import into the "secondary namespace".

5:
Allow selective import of the exact symbol which is required.
import std.string.find; //exact syntax may vary

..find(.. //calls std.string.find

No symbols from std.string would be present in the "secondary namespace".


Opinions/pros/cons on the various solutions
-------------------------------------------

3:
  - PRO,Solves the import conflict for the intended symbol.
  - PRO,Solves future symbol conflicts in the same module(s).
  - CON,Causes more verbose code, using FQN all the time.

4:
  - PRO,Solves the import conflict for the intended symbol.
  - PRO,Solves future symbol conflicts in the same module(s).

5:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.


Conclusions, extra thoughts
---------------------------

The ideal solution IMO is #4, it solves both A and B in a simple, easy and  
elegant(IMO) fashion something that cannot
be said about the existing solutions #1 and #2.

To the people who want FQN all the time.. You may view the proposed  
solutions #3 and #4 as identical (in value to you).
The deciding factor to my mind is that other people do not want to use FQN  
all the time therefore #4 makes the most
people happy. The interesting thing, is that FQN can be achieved with  
soltion #4, note that:
   import std.string std.string;

would be FQN access, without! any further special syntax (like "static"),  
to me this makes #4 better than #3
even if you want to use FQN.

Yes, it requires more typing but I don't think you can complain about  
having to type the module name once more
when you plan to type it 20+ more times in the course of the file, can you?

FQN access is curently always present, but not required. However, with  
solution #4 FQN access to the symbol is no longer
ever required. It's presence results in code which can call the same  
function in more than one way. This allows the code to
be inconsistent for no gain (that I can imagine) therefore i think that  
solution #4 should prevent FQN access to symbols.

This sounds like a very good summary -- I also like the #4 option :) So #4 + private by default? Sounds good to me! option[4].vote++; - jeremy
Jul 12 2006
parent Carlos Santander <csantander619 gmail.com> writes:
Jeremy escribió:
 
 This sounds like a very good summary -- I also like the #4 option :) So #4 +
 private by default? Sounds good to me!
 
 option[4].vote++;
 
 - jeremy
 
 

Same here. I'd also like #5, and I can live without #3. -- Carlos Santander Bernal
Jul 13 2006
prev sibling next sibling parent reply Dave <Dave_member pathlink.com> writes:
Regan Heath wrote:

[lots of great stuff snipped for brevity]

   import std.string std.string;

(forces FQN with the original module name)
 
 FQN access is curently always present, but not required. However, with 
 solution #4 FQN access to the symbol is no longer
 ever required. It's presence results in code which can call the same 
 function in more than one way. This allows the code to
 be inconsistent for no gain (that I can imagine) therefore i think that 
 solution #4 should prevent FQN access to symbols.

I agree with all of your conclusions, with the caveat for compiler writers that the current alias functionality cannot be used internally to implement this given the above two requirements. You can't: alias foo foo; and: alias foo myfoo; doesn't force myfoo to be used over 'foo'. But I think it is all-around the best solution for the same rational given. Given your rational and proposal, the _need_ for "specific symbol import" functionality will probably disappear too, keeping the language that much simpler to implement and less to learn and remember in order to maintain code. import a.popular.db.lib dblib; alias dblib.open dbopen; alias dblib.close dbclose; would be used instead of something like: import a.popular.db.lib dblib { open dbopen; close dbclose; } Not much difference in lines of code or effort to write or scan, the one advantage being that it would tend to keep aliased symbols close to the import (that's still a big advantage though, IMHO).
Jul 12 2006
parent reply kris <foo bar.com> writes:
Suspect we've already flogged this to death a number of times, but 
selective-imports don't appear to give you much functional power above 
and beyond the prefix-import. Thus it would be entirely optional, IMO. I 
know Dave has noted this in a prior post, as have others.

Dave wrote:
 Given your rational and proposal, the _need_ for "specific symbol 
 import" functionality will probably disappear too, keeping the language 
 that much simpler to implement and less to learn and remember in order 
 to maintain code.
 
 import a.popular.db.lib dblib;
 alias dblib.open dbopen;
 alias dblib.close dbclose;
 
 would be used instead of something like:
 
 import a.popular.db.lib dblib
 {
 open dbopen;
 close dbclose;
 }
 
 Not much difference in lines of code or effort to write or scan, the one 
 advantage being that it would tend to keep aliased symbols close to the 
 import (that's still a big advantage though, IMHO).

egad! :) Would perhaps be simpler to avoid that, and just do this instead: import a.popular.db.lib db; db.open (); db.close (); As well as being concise and safe, it also clearly indicates just which instance of open/close is being invoked. Those who don't need safe imports can still happily use the existing variety: import a.popular.lib; open(); close();
Jul 12 2006
parent Dave <Dave_member pathlink.com> writes:
In article <e94d1g$9o3$1 digitaldaemon.com>, kris says...
Suspect we've already flogged this to death a number of times, but 
selective-imports don't appear to give you much functional power above 
and beyond the prefix-import. Thus it would be entirely optional, IMO. I 
know Dave has noted this in a prior post, as have others.

Dave wrote:
 Given your rational and proposal, the _need_ for "specific symbol 
 import" functionality will probably disappear too, keeping the language 
 that much simpler to implement and less to learn and remember in order 
 to maintain code.
 
 import a.popular.db.lib dblib;
 alias dblib.open dbopen;
 alias dblib.close dbclose;
 
 would be used instead of something like:
 
 import a.popular.db.lib dblib
 {
 open dbopen;
 close dbclose;
 }
 
 Not much difference in lines of code or effort to write or scan, the one 
 advantage being that it would tend to keep aliased symbols close to the 
 import (that's still a big advantage though, IMHO).

egad! :) Would perhaps be simpler to avoid that, and just do this instead: import a.popular.db.lib db; db.open (); db.close ();

You're right - I was getting carried away with matching the C# 'using alias = specific_symbol;' functionality because I like it. But, I haven't seen it used by others that much for specific symbols probably for the same reasons your examples just pointed out. I'd be very happy just to get the prefix-import change pretty much like Regan just described.
Jul 12 2006
prev sibling next sibling parent reply "Andrei Khropov" <andkhropov nospam_mtu-net.ru> writes:
Regan Heath wrote:

<skipped>

Good survey, thanks. 

My vote is for #3 as well as #4 to be available (exact syntax may vary).

("import std.string std.string" is disgusting :-) )

-- 
AKhropov
Jul 13 2006
parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Andrei Khropov wrote:
 Regan Heath wrote:
 
 <skipped>
 
 Good survey, thanks. 
 
 My vote is for #3 as well as #4 to be available (exact syntax may vary).
 
 ("import std.string std.string" is disgusting :-) )
 

Yep, I was about to say the same. #3 (FQN import) should be there, regardless of whether #4 (aliasing import, aka prefix import) is or is not as well. As for #4, (basically the same as kris's RFC), I'm not sure yet, but I guess it would be alright. Altough there is something I think I'm not very found of: the ability for one to change the module and/or package name, like this: import foo.string as str; Instead we could have a syntax that would not allow it (and which would also be shorter, but require a keyword other than import): xptoimport foo.string; // makes the name "string" available This is actually basically the same as the selective import, only that it also allows modules and packages themselves to be selectively imported (which is why it requires a new keyword). (For clarity, it can be called universal selective import) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 13 2006
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Regan Heath wrote:
 Proposed solutions
 ------------------
 3:
 Prevent import into the "secondary namespace", only allow FQN access. 
 (AKA "static import")
 static import std.string; //exact syntax may vary
 static import std.regexp; //exact syntax may vary
 
 ..find(.. //error
 ..std.string.find(.. //ok
 ..std.regexp.find(.. //ok
 
 "All 'static import' does is eliminate the "if the name is not found in 
 the current module, look in the imports" step. This has the effect of
 requiring the use of FQN's when referencing imports."
  - Walter
 
 4:
 Import into a custom namespace, eg.
 import std.string str; //exact syntax may vary
 import std.regexp;
 
 ..str.find(.. //calls std.string.find
 ..find(.. //calls std.regexp.find
 
 This method should also prevent import into the "secondary namespace".

Thanks, Regan. Indeed this is an attempt at conflict resolution in both meanings. Well done. Seems to me that one of Walter's key non-negotiables is to ensure that: ------------ import std.stdio; void main() { writefln("Hello, world!"); } ------------ still works. Hopefully all of us can see the importance of that. Personally, I don't have a strong objection to #3, if it was combined with default private imports, we wouldn't have to type "private static import" all the time, which would IMHO be unacceptable. However, unlike Kris, I don't have any experience with working with really large projects in D (or any language at all, actually) -- so I'll trust Kris on the need for #4. #4 would definitely need different syntax, with a clearer visual distinction from a traditional import. Whether it be "import alias std.string str;" or "import std.string as str;" or "import std.string = str;" -- I don't have a strong preference. I don't think there would be any need for it to prevent FQN access. But really, I'll be happy just as long as we're not left with only #1 and #2. I'm delighted that this fundamental issue is finally getting attention; I'm disappointed at how heated the discussion became. Thanks again, Regan.
Jul 13 2006
parent reply Dave <Dave_member pathlink.com> writes:
Don Clugston wrote:
 Regan Heath wrote:
 Proposed solutions
 ------------------
 3:
 Prevent import into the "secondary namespace", only allow FQN access. 
 (AKA "static import")
 static import std.string; //exact syntax may vary
 static import std.regexp; //exact syntax may vary

 ..find(.. //error
 ..std.string.find(.. //ok
 ..std.regexp.find(.. //ok

 "All 'static import' does is eliminate the "if the name is not found 
 in the current module, look in the imports" step. This has the effect of
 requiring the use of FQN's when referencing imports."
  - Walter

 4:
 Import into a custom namespace, eg.
 import std.string str; //exact syntax may vary
 import std.regexp;

 ..str.find(.. //calls std.string.find
 ..find(.. //calls std.regexp.find

 This method should also prevent import into the "secondary namespace".

Thanks, Regan. Indeed this is an attempt at conflict resolution in both meanings. Well done. Seems to me that one of Walter's key non-negotiables is to ensure that: ------------ import std.stdio; void main() { writefln("Hello, world!"); } ------------ still works. Hopefully all of us can see the importance of that. Personally, I don't have a strong objection to #3, if it was combined with default private imports, we wouldn't have to type "private static import" all the time, which would IMHO be unacceptable. However, unlike Kris, I don't have any experience with working with really large projects in D (or any language at all, actually) -- so I'll trust Kris on the need for #4. #4 would definitely need different syntax, with a clearer visual distinction from a traditional import. Whether it be "import alias std.string str;" or "import std.string as str;" or "import std.string = str;" -- I don't have a strong preference. I don't think there would be any need for it to prevent FQN access.

import std.string as string; // Ok, but new keyword import std.string : string; // Ok import std.string string; // Ok: alias-like syntax but not very distinct import std.string = string; // wrong, = is right-assoc. import string = std.string; // Ok: concise, distinct, consistent and logically accurate. I personally like the last because it's the most visually distinctive (makes it hard to miss the alias) and it represents exactly what is going on, but whatever. I agree there would be no need to prevent FQN access. So there would be no need to allow 'import std.string = std.string;' to force the FQN to use the original name. Ergo, the current implementation of alias along with the Walter's 'static import' could be used to implement this type of syntax (internal to the compiler) I believe.
 But really, I'll be happy just as long as we're not left with only #1 
 and #2. I'm delighted that this fundamental issue is finally getting 
 attention; I'm disappointed at how heated the discussion became.
 
 Thanks again, Regan.

Jul 13 2006
parent reply Jeremy <Jeremy_member pathlink.com> writes:
In article <e95lvr$2t28$1 digitaldaemon.com>, Dave says...
Don Clugston wrote:
 Regan Heath wrote:
 Proposed solutions
 ------------------
 3:
 Prevent import into the "secondary namespace", only allow FQN access. 
 (AKA "static import")
 static import std.string; //exact syntax may vary
 static import std.regexp; //exact syntax may vary

 ..find(.. //error
 ..std.string.find(.. //ok
 ..std.regexp.find(.. //ok

 "All 'static import' does is eliminate the "if the name is not found 
 in the current module, look in the imports" step. This has the effect of
 requiring the use of FQN's when referencing imports."
  - Walter

 4:
 Import into a custom namespace, eg.
 import std.string str; //exact syntax may vary
 import std.regexp;

 ..str.find(.. //calls std.string.find
 ..find(.. //calls std.regexp.find

 This method should also prevent import into the "secondary namespace".

Thanks, Regan. Indeed this is an attempt at conflict resolution in both meanings. Well done. Seems to me that one of Walter's key non-negotiables is to ensure that: ------------ import std.stdio; void main() { writefln("Hello, world!"); } ------------ still works. Hopefully all of us can see the importance of that. Personally, I don't have a strong objection to #3, if it was combined with default private imports, we wouldn't have to type "private static import" all the time, which would IMHO be unacceptable. However, unlike Kris, I don't have any experience with working with really large projects in D (or any language at all, actually) -- so I'll trust Kris on the need for #4. #4 would definitely need different syntax, with a clearer visual distinction from a traditional import. Whether it be "import alias std.string str;" or "import std.string as str;" or "import std.string = str;" -- I don't have a strong preference. I don't think there would be any need for it to prevent FQN access.

import std.string as string; // Ok, but new keyword

I like this one the best. It is so "readable" while not being too wordy.
import string = std.string; // Ok: concise, distinct, consistent and 
logically accurate.

That just looks odd to me... it looks like "import" is some data type, and your assigning some value "std.string" to "string". It also is very different from 'normal' import lines: import std.string; import std.string as str; vs. import std.string; import str = std.string; Putting "as str" at the end of the import is more intuitive than putting a "str =" in the middle of the import line... disclaimer: add IMHO to all my statements :)
I personally like the last because it's the most visually distinctive 
(makes it hard to miss the alias) and it represents exactly what is 
going on, but whatever.

I agree there would be no need to prevent FQN access. So there would be 
no need to allow 'import std.string = std.string;' to force the FQN to 
use the original name.

Ergo, the current implementation of alias along with the Walter's 
'static import' could be used to implement this type of syntax (internal 
to the compiler) I believe.

 But really, I'll be happy just as long as we're not left with only #1 
 and #2. I'm delighted that this fundamental issue is finally getting 
 attention; I'm disappointed at how heated the discussion became.
 
 Thanks again, Regan.


- Jeremy
Jul 13 2006
parent Dave <Dave_member pathlink.com> writes:
Jeremy wrote:
 In article <e95lvr$2t28$1 digitaldaemon.com>, Dave says...
 Don Clugston wrote:
 Regan Heath wrote:
 Proposed solutions
 ------------------
 3:
 Prevent import into the "secondary namespace", only allow FQN access. 
 (AKA "static import")
 static import std.string; //exact syntax may vary
 static import std.regexp; //exact syntax may vary

 ..find(.. //error
 ..std.string.find(.. //ok
 ..std.regexp.find(.. //ok

 "All 'static import' does is eliminate the "if the name is not found 
 in the current module, look in the imports" step. This has the effect of
 requiring the use of FQN's when referencing imports."
  - Walter

 4:
 Import into a custom namespace, eg.
 import std.string str; //exact syntax may vary
 import std.regexp;

 ..str.find(.. //calls std.string.find
 ..find(.. //calls std.regexp.find

 This method should also prevent import into the "secondary namespace".

Thanks, Regan. Indeed this is an attempt at conflict resolution in both meanings. Well done. Seems to me that one of Walter's key non-negotiables is to ensure that: ------------ import std.stdio; void main() { writefln("Hello, world!"); } ------------ still works. Hopefully all of us can see the importance of that. Personally, I don't have a strong objection to #3, if it was combined with default private imports, we wouldn't have to type "private static import" all the time, which would IMHO be unacceptable. However, unlike Kris, I don't have any experience with working with really large projects in D (or any language at all, actually) -- so I'll trust Kris on the need for #4. #4 would definitely need different syntax, with a clearer visual distinction from a traditional import. Whether it be "import alias std.string str;" or "import std.string as str;" or "import std.string = str;" -- I don't have a strong preference. I don't think there would be any need for it to prevent FQN access.


I like this one the best. It is so "readable" while not being too wordy.
 import string = std.string; // Ok: concise, distinct, consistent and 
 logically accurate.

That just looks odd to me... it looks like "import" is some data type, and your assigning some value "std.string" to "string". It also is very different from 'normal' import lines: import std.string; import std.string as str; vs. import std.string; import str = std.string; Putting "as str" at the end of the import is more intuitive than putting a "str =" in the middle of the import line... disclaimer: add IMHO to all my statements :)

Seems others agree with you - note your preferences here if you want: http://www.prowiki.org/wiki4d/wiki.cgi?ImportConflictResolution
Jul 13 2006
prev sibling next sibling parent reply Lucas Goss <lgoss007 gmail.com> writes:
Regan Heath wrote:
 Here is my current understanding of the problems and solutions proposed 
 to date. Comments are welcome, including "enough already! the horse is 
 dead!" ;)
 ...

Nice! Wiki'd! http://www.prowiki.org/wiki4d/wiki.cgi?ImportConflictResolution And linked from: http://www.prowiki.org/wiki4d/wiki.cgi?ImportIssues I added a section for supported solutions so you can put your name by the number you support (makes me feel like I'm signing a declaration of... independence or something, :) ). Lucas
Jul 13 2006
parent reply Dave <Dave_member pathlink.com> writes:
Lucas Goss wrote:
 Regan Heath wrote:
 Here is my current understanding of the problems and solutions 
 proposed to date. Comments are welcome, including "enough already! the 
 horse is dead!" ;)
 ...

Nice! Wiki'd! http://www.prowiki.org/wiki4d/wiki.cgi?ImportConflictResolution And linked from: http://www.prowiki.org/wiki4d/wiki.cgi?ImportIssues I added a section for supported solutions so you can put your name by the number you support (makes me feel like I'm signing a declaration of... independence or something, :) ). Lucas

I added a Preferred Syntax section too, FWIW. - Dave
Jul 13 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 13 Jul 2006 10:06:25 -0500, Dave <Dave_member pathlink.com> wrote:
 Lucas Goss wrote:
 Regan Heath wrote:
 Here is my current understanding of the problems and solutions  
 proposed to date. Comments are welcome, including "enough already! the  
 horse is dead!" ;)
 ...

http://www.prowiki.org/wiki4d/wiki.cgi?ImportConflictResolution And linked from: http://www.prowiki.org/wiki4d/wiki.cgi?ImportIssues I added a section for supported solutions so you can put your name by the number you support (makes me feel like I'm signing a declaration of... independence or something, :) ). Lucas

I added a Preferred Syntax section too, FWIW.

Thanks guys, it looks good. Regan
Jul 13 2006
parent reply Jeremy <Jeremy_member pathlink.com> writes:
In article <optcnfgdgc23k2f5 nrage>, Regan Heath says...
On Thu, 13 Jul 2006 10:06:25 -0500, Dave <Dave_member pathlink.com> wrote:
 Lucas Goss wrote:
 Regan Heath wrote:
 Here is my current understanding of the problems and solutions  
 proposed to date. Comments are welcome, including "enough already! the  
 horse is dead!" ;)
 ...

http://www.prowiki.org/wiki4d/wiki.cgi?ImportConflictResolution And linked from: http://www.prowiki.org/wiki4d/wiki.cgi?ImportIssues I added a section for supported solutions so you can put your name by the number you support (makes me feel like I'm signing a declaration of... independence or something, :) ). Lucas

I added a Preferred Syntax section too, FWIW.

Thanks guys, it looks good. Regan

Doesn't the "import a.b.c : a;" syntax break the context-free parsing thingy? I don't know much about it, but couldn't the colon get confused with the colon in "a = b ? 1 : 2;" stuff? - jeremy
Jul 13 2006
parent reply kris <foo bar.com> writes:
Jeremy wrote:

 Doesn't the "import a.b.c : a;" syntax break the context-free parsing thingy? I
 don't know much about it, but couldn't the colon get confused with the colon in
 "a = b ? 1 : 2;" stuff?
 
 - jeremy
 
 

Unlikely. The ":" or "as" or whatever is simply /noise/ -- something that is primarily optional for the underlying parser. It does depend on the parser, but DMD is an RD variety so can handle it without issue. In other words, whatever goes in there is not really a keyword in the traditional sense?
Jul 13 2006
parent kellywilson nowhere.com writes:
Hey Kris and Jeremy,

Kris: You are correct that this construct will not have much of an effect on the
dmd frontend, as far a parsing goes (semantically, it shouldn't be a big issue
either, I believe). As far as the ":" or "as" keywords being \noise\, they are
actually TERMINALS in my grammar and thus can be "ignored" if there is anther
rule that matches the input without said terminals. ie:

nonterm(Decl*) ImportDeclaration {
-> IMPORT x:ImportNames SEMI
-> IMPORT x:ImportNames COLON Identifier SEMI
}

The rules above (the example is in my parser - using Elkhound syntax) show that
we can easily match an "ImportDeclaration" using either "import x.y;" or "import
x.y : something;"

The terminal ":" is a keyword that already exists in the lexer. The terminal
"as" would still be a keyword "in the traditional sense", if used, and would
need to be added to the lexer. It would not be a big deal to add to my lexer or
parser, however.


I assume what Jeremy means by the "context-free" thingy is actually a concern
with added ambiguities or conflicts. My parser doesn't have any extra
ambiguities when adding the ":" or "as" keyword to the ImportDeclaration rule of
the parser. There are no extra conflicts (shift/reduce or reduce/reduce for the
parser guys) added by this new rule, either.

If anyone has any other syntactic additions that they would like to test, I can
easily add them to my parser to check for conflicts/ambiguities. The semantics
will have to be checked by Walter in his frontend. If I find some time soon, I
will try to get my parser code into shape (and upgrade to version 0.162) for
release on dsource.org, so that others can test out new syntax ideas, as well.
Semantic checking may come when version 1.0 is available.

Thanks,
K.Wilson

P.S. Hey Jeremy...D is not without ambiguities in the (0.149) spec/version that
I worked off of. There are several ambiguities that the dmd frontend deals with
(and Walter has discussed before, I believe). I have about 4 ambiguities in my
grammar. I also have a lot of conflicts which are dealt with using default
conflict resolution schemes at the moment (semantic checking, when added, would
deal with some of these conflicts differently).


In article <e96khi$aql$1 digitaldaemon.com>, kris says...
Jeremy wrote:

 Doesn't the "import a.b.c : a;" syntax break the context-free parsing thingy? I
 don't know much about it, but couldn't the colon get confused with the colon in
 "a = b ? 1 : 2;" stuff?
 
 - jeremy
 
 

Unlikely. The ":" or "as" or whatever is simply /noise/ -- something that is primarily optional for the underlying parser. It does depend on the parser, but DMD is an RD variety so can handle it without issue. In other words, whatever goes in there is not really a keyword in the traditional sense?

Jul 14 2006
prev sibling parent reply Georg Wrede <georg.wrede nospam.org> writes:
Regan Heath wrote:
 Here is my current understanding of the problems and solutions proposed 
 to  date. Comments are welcome, including "enough already! the horse is 
 dead!"  ;)
 
 Regan
 
 
 Import conflict resolution
 --------------------------
 
 Assumptions
 -----------
 Imports are private by default (Walter seems to like this now?)
 
 
 Terminology
 -----------
 FQN = Fully Qualified Name
 
 
 Problems
 --------
 A:
 Importing 2 modules with the same symbol causes an immediate collision eg.
 import std.string;
 import std.regexp;
 
 ..find(.. //error std.string.find or std.regexp.find
 
 B:
 Changes to a module at a later date may cause a collision at a later date.
 import a;
 import b;
 
 ..foo(.. //calling a.foo.
 
 At later date symbol 'foo' is added to b and now the collision occurs.
 
 
 Current behaviour
 -----------------
 "How imports work is that first a name is searched for in the current  
 namespace. If it is not found, then it is looked for in the import 
 list.  If it is
 found uniquely among the imports, then that is used. If it is in more 
 than  one import, an error occurs"
  - Walter
 
 "Import does not import names into the current namespace. It imports 
 them  into a secondary namespace, that is looked in *only* if the name 
 isn't
 found in the current namespace. Alias can then cherry-pick specific  
 symbols out of that secondary namespace and put them in the current  
 namespace,
 possibly renaming them along the way."
  - Walter
 
 
 Current solutions
 -----------------
 1:
 import std.string;
 import std.regexp;
 alias std.string.find find;
 
 ..find(.. //no error std.string.find is called
 
 2:
 import std.string;
 import std.regexp;
 
 ..std.string.find(.. //no error FQN is used
 
 
 Opinions/pros/cons on the current solutions
 -------------------------------------------
 
 1:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
  - CON,The alias is 'physically' seperate from the import.
 
 2:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
  - CON,Causes more verbose code.
 
 Neither of these current solutions solves B.
 
 
 Proposed solutions
 ------------------
 3:
 Prevent import into the "secondary namespace", only allow FQN access. 
 (AKA  "static import")
 static import std.string; //exact syntax may vary
 static import std.regexp; //exact syntax may vary
 
 ..find(.. //error
 ..std.string.find(.. //ok
 ..std.regexp.find(.. //ok
 
 "All 'static import' does is eliminate the "if the name is not found in  
 the current module, look in the imports" step. This has the effect of
 requiring the use of FQN's when referencing imports."
  - Walter
 
 4:
 Import into a custom namespace, eg.
 import std.string str; //exact syntax may vary
 import std.regexp;
 
 ..str.find(.. //calls std.string.find
 ..find(.. //calls std.regexp.find
 
 This method should also prevent import into the "secondary namespace".
 
 5:
 Allow selective import of the exact symbol which is required.
 import std.string.find; //exact syntax may vary
 
 ..find(.. //calls std.string.find
 
 No symbols from std.string would be present in the "secondary namespace".
 
 
 Opinions/pros/cons on the various solutions
 -------------------------------------------
 
 3:
  - PRO,Solves the import conflict for the intended symbol.
  - PRO,Solves future symbol conflicts in the same module(s).
  - CON,Causes more verbose code, using FQN all the time.
 
 4:
  - PRO,Solves the import conflict for the intended symbol.
  - PRO,Solves future symbol conflicts in the same module(s).
 
 5:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.
 
 
 Conclusions, extra thoughts
 ---------------------------
 
 The ideal solution IMO is #4, it solves both A and B in a simple, easy 
 and  elegant(IMO) fashion something that cannot
 be said about the existing solutions #1 and #2.
 
 To the people who want FQN all the time.. You may view the proposed  
 solutions #3 and #4 as identical (in value to you).
 The deciding factor to my mind is that other people do not want to use 
 FQN  all the time therefore #4 makes the most
 people happy. The interesting thing, is that FQN can be achieved with  
 soltion #4, note that:
   import std.string std.string;
 
 would be FQN access, without! any further special syntax (like 
 "static"),  to me this makes #4 better than #3
 even if you want to use FQN.
 
 Yes, it requires more typing but I don't think you can complain about  
 having to type the module name once more
 when you plan to type it 20+ more times in the course of the file, can you?
 
 FQN access is curently always present, but not required. However, with  
 solution #4 FQN access to the symbol is no longer
 ever required. It's presence results in code which can call the same  
 function in more than one way. This allows the code to
 be inconsistent for no gain (that I can imagine) therefore i think that  
 solution #4 should prevent FQN access to symbols.

Out of these, I'd want #4 and #5 combined. Except that I don't understand the following:
 5:
 Allow selective import of the exact symbol which is required.
 import std.string.find; //exact syntax may vary

 ..find(.. //calls std.string.find

 No symbols from std.string would be present in the "secondary namespace".


 Opinions/pros/cons on the various solutions
 -------------------------------------------

 5:
  - PRO,Solves the import conflict for the intended symbol.
  - CON,Does NOT solve future symbol conflicts.

It was stated that "No symbols from std.string would be present in the "secondary namespace". Therefore I don't understand the CON argument "Does NOT solve future symbol conflicts". ----------------- Anyhow, I officially want to 1: be able to import a module into an arbitrary namespace import foo.bar.baz.gawk.gasp.stuff as crap; or even import foo.bar.baz.gawk.gasp.stuff as foo.bar.baz.gawk.gasp.stuff; // if I so care to choose. ;-/ 2: be able to import arbitrary module-top-level-identifiers, without importing the rest of the module import da.njet.ruskiij.svesda.myfunc as f; 3: retain compatibility with legacy D code import foo.bar; // All of both go to the "secondary name space", import baz.baw; // as hitherto. (With risk of conflict. :-) ) 1, 2 and 3 should all be usable in the same file! import foo.fii.faa; import doo.dii.daa.aFunc as df; import boo.bii.baa as b; ---- So, Regan, you may count my contribution as you like, here I've just presented what I honestly want, without careful regard [or precise understanding] of the Numbered Categories. ################################ And even here I have to beg, crawl, kiss A, threat, --- or just ask Walter: Pretty please, please do include the word "as" in the import statement, please! I know that it's not needed (i.e., a space would do), I know there are numerous other alternatives ":", "=", you-name-it. But for the educational motivations you _yourself_ brought up a couple of messages ago, and for corporate code maintenance, or newbie fluency issues (which nobody has yet brought up), please retain the word "as" here. It really doesn't waste /that/ much of ink.
Jul 13 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede <georg.wrede nospam.org>  
wrote:
<snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary  
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in the  
 "secondary namespace". Therefore I don't understand the CON argument  
 "Does NOT solve future symbol conflicts".

I guess it can be argued either way. #5 does avoid future symbol collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.
 -----------------

 Anyhow, I officially want to

 1: be able to import a module into an arbitrary namespace

      import foo.bar.baz.gawk.gasp.stuff as crap;

#4
 or even

      import foo.bar.baz.gawk.gasp.stuff as foo.bar.baz.gawk.gasp.stuff;
      // if I so care to choose. ;-/

#4
 2: be able to import arbitrary module-top-level-identifiers, without  
 importing the rest of the module

      import da.njet.ruskiij.svesda.myfunc as f;

#5 + #4
 3: retain compatibility with legacy D code

      import foo.bar;  // All of both go to the "secondary name space",
      import baz.baw;  // as hitherto. (With risk of conflict. :-)  )

None of the proposals affect the existing import behaviour.
 1, 2 and 3 should all be usable in the same file!

      import foo.fii.faa;
      import doo.dii.daa.aFunc as df;
      import boo.bii.baa as b;

No problem, the proposals are not mutually exclusive.
 So, Regan, you may count my contribution as you like, here I've just  
 presented what I honestly want, without careful regard [or precise  
 understanding] of the Numbered Categories.

You could add your support here: http://www.prowiki.org/wiki4d/wiki.cgi?ImportConflictResolution you can even add your own desired syntax.
 ################################

 And even here I have to beg, crawl, kiss A, threat, --- or just ask  
 Walter:

     Pretty please, please do include the word "as" in the import  
 statement, please!

 I know that it's not needed (i.e., a space would do), I know there are  
 numerous other alternatives ":", "=", you-name-it.

 But for the educational motivations you _yourself_ brought up a couple  
 of messages ago, and for corporate code maintenance, or newbie fluency  
 issues (which nobody has yet brought up), please retain the word "as"  
 here.

 It really doesn't waste /that/ much of ink.

As Don said and I tend to agree.. "#4 would definitely need different syntax, with a clearer visual distinction from a traditional import. Whether it be "import alias std.string str;" or "import std.string as str;" or "import std.string = str;" -- I don't have a strong preference." -Don Clugston Regan
Jul 14 2006
next sibling parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede <georg.wrede nospam.org> 
 wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary 
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in the 
 "secondary namespace". Therefore I don't understand the CON argument 
 "Does NOT solve future symbol conflicts".

I guess it can be argued either way. #5 does avoid future symbol collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

What do you mean "when you do want more access you have to specify each and every symbol"? You mean having to use FQN? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 14 2006
parent reply =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

I guess it can be argued either way. #5 does avoid future symbol collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

What do you mean "when you do want more access you have to specify each and every symbol"? You mean having to use FQN?

When selectively importing you only have access to the symbols that are listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace). -- Jari-Matti
Jul 14 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Jari-Matti Mäkelä wrote:
 Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

and every symbol"? You mean having to use FQN?

When selectively importing you only have access to the symbols that are listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace).

I didn't understand that "- not." in the first statement. I'm assuming it wasn't supposed to be there. So, yes, with selective import you only have access to the symbols that are listed in the import, but that is the same as #4's aliasing import: import std.string str; //exact syntax may vary Here only the name 'str' is imported, if you want to import another symbol, you also have to add another import. Isn't that so? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 15 2006
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 15 Jul 2006 10:59:13 +0100, Bruno Medeiros  
<brunodomedeirosATgmail SPAM.com> wrote:
 Jari-Matti Mäkelä wrote:
 Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

and every symbol"? You mean having to use FQN?

listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace).

I didn't understand that "- not." in the first statement. I'm assuming it wasn't supposed to be there. So, yes, with selective import you only have access to the symbols that are listed in the import, but that is the same as #4's aliasing import: import std.string str; //exact syntax may vary Here only the name 'str' is imported, if you want to import another symbol, you also have to add another import. Isn't that so?

No. #4 "import std.string str;" imports _all_ the symbols from std.string into a namespace/prefix called "str". So, the difference is this: import std.string str; str.find(); // ok, calls std.string.find str.tolower(); // ok, calls std.string.tolower import std.string.find; find(); // ok, calls std.string.find tolower(); // error, std.string.tolower has not been imported. Regan
Jul 15 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Regan Heath wrote:
 On Sat, 15 Jul 2006 10:59:13 +0100, Bruno Medeiros 
 <brunodomedeirosATgmail SPAM.com> wrote:
 Jari-Matti Mäkelä wrote:
 Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

and every symbol"? You mean having to use FQN?

listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace).

I didn't understand that "- not." in the first statement. I'm assuming it wasn't supposed to be there. So, yes, with selective import you only have access to the symbols that are listed in the import, but that is the same as #4's aliasing import: import std.string str; //exact syntax may vary Here only the name 'str' is imported, if you want to import another symbol, you also have to add another import. Isn't that so?

No. #4 "import std.string str;" imports _all_ the symbols from std.string into a namespace/prefix called "str". So, the difference is this:

Which is the same to say that it imports the 'str' symbol (which is 'std.string') into the current namespace.
 
 import std.string str;
 str.find();    // ok, calls std.string.find
 str.tolower(); // ok, calls std.string.tolower
 
 import std.string.find;
 find();    // ok, calls std.string.find
 tolower(); // error, std.string.tolower has not been imported.
 
 Regan
 

But I get your point. (did you see my comment about the universal selective import?) -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 15 2006
parent "Regan Heath" <regan netwin.co.nz> writes:
On Sat, 15 Jul 2006 12:43:16 +0100, Bruno Medeiros  
<brunodomedeirosATgmail SPAM.com> wrote:
 Regan Heath wrote:
 On Sat, 15 Jul 2006 10:59:13 +0100, Bruno Medeiros  
 <brunodomedeirosATgmail SPAM.com> wrote:
 Jari-Matti Mäkelä wrote:
 Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

each and every symbol"? You mean having to use FQN?

are listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace).

I didn't understand that "- not." in the first statement. I'm assuming it wasn't supposed to be there. So, yes, with selective import you only have access to the symbols that are listed in the import, but that is the same as #4's aliasing import: import std.string str; //exact syntax may vary Here only the name 'str' is imported, if you want to import another symbol, you also have to add another import. Isn't that so?

std.string into a namespace/prefix called "str". So, the difference is this:

Which is the same to say that it imports the 'str' symbol (which is 'std.string') into the current namespace.

Yes, I guess you could say that.. tho I don't really think of 'str' as being a symbol so much as an alias (another name) for a package/module. Would you call a package/module a symbol? I guess you could.
  import std.string str;
 str.find();    // ok, calls std.string.find
 str.tolower(); // ok, calls std.string.tolower
  import std.string.find;
 find();    // ok, calls std.string.find
 tolower(); // error, std.string.tolower has not been imported.
  Regan

But I get your point. (did you see my comment about the universal selective import?)

Yes. I personally prefer the more explicit nature of #4, eg. "import std.string as string" mentions both "std.string" and "string" in the statement. "SELECTIVEIMPORT std.string" mentions only "std.string" but not (explicitly) "string". I think #4 is more obvious to the newcomer or the casual observer and the cost of typing a few more letters in one place. Regan
Jul 15 2006
prev sibling next sibling parent Tyro <Tyro_member pathlink.com> writes:
In article <e9ae71$d4j$1 digitaldaemon.com>, Bruno Medeiros says...
Jari-Matti Mäkelä wrote:
 Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

and every symbol"? You mean having to use FQN?

When selectively importing you only have access to the symbols that are listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace).

I didn't understand that "- not." in the first statement. I'm assuming it wasn't supposed to be there. So, yes, with selective import you only have access to the symbols that are listed in the import, but that is the same as #4's aliasing import: import std.string str; //exact syntax may vary Here only the name 'str' is imported, if you want to import another symbol, you also have to add another import. Isn't that so?

No! In selectively importing std.string.find you are only importing the find() method from the module std.string. This allows you access to std.string.find() but nothing else from that module. | import std.string.find; | | void main() | { | char[] s = "Something to find"; | find(s, "to"); // Ok | std.string.find(s, "find"); // Ok? | char[][] words; | words = std.string.split(s); // Illegal | } With option #4 you are importing the entire std.string module into a namespace called "str" (or whatever else you'd like) and you have complete access to the symbols from that module through str. | import std.string as str; | | void main() | { | char[] s = "Something to find"; | find(s, "to"); // Illegal | str.find(s, "to"); // Ok | std.string.find(s, "find"); // Illegal | str.find(s, "find"); // Ok | char[][] words; | wirds = split(s); // Illegal | words = std.string.split(s); // Illegal | words = str.split(s); // Ok | }
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D

Andrew Edwards
Jul 15 2006
prev sibling parent =?ISO-8859-15?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Bruno Medeiros wrote:
 Jari-Matti Mäkelä wrote:
 Bruno Medeiros wrote:
 Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede
 <georg.wrede nospam.org> wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in
 the "secondary namespace". Therefore I don't understand the CON
 argument "Does NOT solve future symbol conflicts".

collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

and every symbol"? You mean having to use FQN?

When selectively importing you only have access to the symbols that are listed in the import statement - not. If you want to import yet another symbol, you have to explicitly add it to the imports - every time. But when using #4, new accessible symbols are automagically imported to a secondary namespace).

I didn't understand that "- not." in the first statement. I'm assuming it wasn't supposed to be there.

No. I was in a bit hurry and forgot that. I wanted to say that it does not import the whole module.
Jul 15 2006
prev sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Regan Heath wrote:
 On Fri, 14 Jul 2006 08:29:59 +0300, Georg Wrede <georg.wrede nospam.org> 
 wrote:
 <snip>
 Out of these, I'd want #4 and #5 combined.

 Except that I don't understand the following:

  > 5:
  > Allow selective import of the exact symbol which is required.
  > import std.string.find; //exact syntax may vary
  >
  > ..find(.. //calls std.string.find
  >
  > No symbols from std.string would be present in the "secondary 
 namespace".
  >
  >
  > Opinions/pros/cons on the various solutions
  > -------------------------------------------
  >
  > 5:
  >  - PRO,Solves the import conflict for the intended symbol.
  >  - CON,Does NOT solve future symbol conflicts.

 It was stated that "No symbols from std.string would be present in the 
 "secondary namespace". Therefore I don't understand the CON argument 
 "Does NOT solve future symbol conflicts".

I guess it can be argued either way. #5 does avoid future symbol collisions (from std.string) but only by virtue of importing no other symbols. In other words the cost of avoiding a collision is not having access to other symbols. So, when you do want more access you have to specify each and every symbol. This solution is too micro-management for my liking.

I'm updating the Wiki then. The CON for #5 is not that it "Does NOT solve future symbol conflicts." but rather that is it very verbose when importing many symbols from the same module. I've also added my proposal of a universal selective import. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 15 2006