www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal for an extension to the import syntax

reply Downs <mathis.beer tu-ilmenau.de> writes:
At the moment the phobos standard library packages form a very flat structure.
However, it can be anticipated that with the availability of a 1.0 spec, more
libraries written natively in D will arise.
These libraries may have a far deeper and more branched package structure.
Since D does not have a construct similar to Java's "import module.*",
this will lead to pagefuls of import, consisting mostly of redundant
information, and we all know redundancy is sin ^^
Thus I propose an extension to the import syntax similar in meaning to the
following example:
   import package.sub_package.vendor.[module_a, module_b, module_c];
These groups could possibly be used recursively, e.g.
   import package.sub_package.vendor.[module_a.[sub1, sub2], module_b];

Any feedback, improvements, criticisms are appreciated.
Greetings.
Dec 11 2006
next sibling parent =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Downs wrote:

 At the moment the phobos standard library packages form a very flat 
 structure.
 However, it can be anticipated that with the availability of a 1.0 spec, 
 more libraries written natively in D will arise.
 These libraries may have a far deeper and more branched package structure.
 Since D does not have a construct similar to Java's "import module.*",
 this will lead to pagefuls of import, consisting mostly of redundant
 information, and we all know redundancy is sin ^^

The usual workaround is to have an "umbrella" module of module/module.d, so that you can import module.module; to get the usual modules imported. See http://www.prowiki.org/wiki4d/wiki.cgi?BestPractices #ConventionalModuleNameforImportingAllModulesinaPackage --anders
Dec 11 2006
prev sibling next sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Downs wrote:
 At the moment the phobos standard library packages form a very flat 
 structure.
 However, it can be anticipated that with the availability of a 1.0 spec, 
 more libraries written natively in D will arise.
 These libraries may have a far deeper and more branched package structure.
 Since D does not have a construct similar to Java's "import module.*",
 this will lead to pagefuls of import, consisting mostly of redundant
 information, and we all know redundancy is sin ^^
 Thus I propose an extension to the import syntax similar in meaning to 
 the following example:
   import package.sub_package.vendor.[module_a, module_b, module_c];
 These groups could possibly be used recursively, e.g.
   import package.sub_package.vendor.[module_a.[sub1, sub2], module_b];
 
 Any feedback, improvements, criticisms are appreciated.
 Greetings.

I'll say this much. Generally speaking, I am against adding anymore to D's import system as it stands -- it was an amazing sight when we got private-by-default, import aliasing, selective imports, and static imports. All of these things which had been wanted at one time or another, and thought impossible to achieve all at once. But Walter had one of his genius moments and invented a syntax that does provide all these, in a very reasonable manner. (Go W!) However, in the process, he did make it a little fragile. I don't know if it could handle having anymore shoved into it than it has now. /BUT/, I do have to admit your syntax at the very least is strangely compelling. ;) I think the longest import list I've ever had in a single module (not counting umbrella modules) was about ten. I consider ten to be perfectly acceptable; so I don't know if I agree about deep libraries (Mango can get there sometimes) causing a problem... but I guess massive multi-libs and such might later on. It has my cautious vote. -- Chris Nicholson-Sauls
Dec 11 2006
parent reply "John Reimer" <terminal.node gmail.com> writes:
On Mon, 11 Dec 2006 12:39:36 -0800, Chris Nicholson-Sauls  
<ibisbasenji gmail.com> wrote:

 Downs wrote:
 At the moment the phobos standard library packages form a very flat  
 structure.
 However, it can be anticipated that with the availability of a 1.0  
 spec, more libraries written natively in D will arise.
 These libraries may have a far deeper and more branched package  
 structure.
 Since D does not have a construct similar to Java's "import module.*",
 this will lead to pagefuls of import, consisting mostly of redundant
 information, and we all know redundancy is sin ^^
 Thus I propose an extension to the import syntax similar in meaning to  
 the following example:
   import package.sub_package.vendor.[module_a, module_b, module_c];
 These groups could possibly be used recursively, e.g.
   import package.sub_package.vendor.[module_a.[sub1, sub2], module_b];
  Any feedback, improvements, criticisms are appreciated.
 Greetings.

I'll say this much. Generally speaking, I am against adding anymore to D's import system as it stands -- it was an amazing sight when we got private-by-default, import aliasing, selective imports, and static imports. All of these things which had been wanted at one time or another, and thought impossible to achieve all at once. But Walter had one of his genius moments and invented a syntax that does provide all these, in a very reasonable manner. (Go W!) However, in the process, he did make it a little fragile. I don't know if it could handle having anymore shoved into it than it has now. /BUT/, I do have to admit your syntax at the very least is strangely compelling. ;) I think the longest import list I've ever had in a single module (not counting umbrella modules) was about ten. I consider ten to be perfectly acceptable; so I don't know if I agree about deep libraries (Mango can get there sometimes) causing a problem... but I guess massive multi-libs and such might later on. It has my cautious vote. -- Chris Nicholson-Sauls

Massive imports will happen. It's only a matter of time as huge projects start rolling out. "all.d" has been a popular workaround. But, once again, I think all.d is not optimal and only acts as a red flag that reveals a future need. I think in circumstances like this, Walter is willing to wait until experience forces the issue back to the forefront (and I think it will reappear). In fact, I'm sure this is the way many new D features will appear in the future, especially as complex cases start identifying needs in large commercial projects. I do think we need a muli-import style eventually -- something that is safe, something that is clear in regards to intent. The suggestion made by downs is a start and shows a alertness to the potential problems of a multi-import syntax. Maybe the idea can be further developed to improve the syntax. -JJR
Dec 11 2006
next sibling parent BCS <BCS pathlink.com> writes:
John Reimer wrote:
 
 Massive imports will happen.  It's only a matter of time as huge 
 projects  start rolling out.  "all.d" has been a popular workaround.  
 But, once  again, I think all.d is not optimal and only acts as a red 
 flag that  reveals a future need.
 
 I think in circumstances like this, Walter is willing to wait until  
 experience forces the issue back to the forefront (and I think it will  
 reappear). In fact, I'm sure this is the way many new D features will  
 appear in the future, especially as complex cases start identifying 
 needs  in large commercial projects.
 
 I do think we need a muli-import style eventually -- something that is  
 safe, something that is clear in regards to intent.  The suggestion 
 made  by downs is a start and shows a alertness to the potential 
 problems of a  multi-import syntax.  Maybe the idea can be further 
 developed to improve  the syntax.
 
 -JJR

Good points. I think that operational model of "don't fix things that don't need it" is a good idea. That is as long as you DO fix things that need it and keep an eye to things that might. Avoiding adding unneeded features to early allow more flexibility later when working on things that do need fixing.
Dec 11 2006
prev sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
John Reimer wrote:
 On Mon, 11 Dec 2006 12:39:36 -0800, Chris Nicholson-Sauls 
 <ibisbasenji gmail.com> wrote:

 Massive imports will happen.  It's only a matter of time as huge 
 projects start rolling out.  "all.d" has been a popular workaround.  
 But, once again, I think all.d is not optimal and only acts as a red 
 flag that reveals a future need.

I would also like to take this opportunity to point out that the current selective import does not obey protection attributes. That is, if you do a selective import like: private import std.stdio : writefln; writefln will leak out to other modules that import this one, despite the 'private' attribute. (and yes I know private is the default, just put it there for emphasis). http://d.puremagic.com/issues/show_bug.cgi?id=604 I think this is another issue that will start to bite more people in the rump as project sizes grow. --bb
Dec 11 2006
prev sibling parent reply Trevor Parscal <trevorparscal hotmail.com> writes:
Why not just use

import package.*;

it makes sense in regexp statements, it works for java, why not use it here?
What's the problem?
Dec 11 2006
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Trevor Parscal wrote:
 Why not just use
 
 import package.*;
 
 it makes sense in regexp statements, it works for java, why not use it here?
 What's the problem?

Problems: 1 - Inexpressiveness. (Is that a word?) Assuming a random reader, peer reviewer, maintenance coder, or what have you is fully familiar with the library/package being imported, then there is no problem in this sense. Assuming they are less than fully familiar -- probably far more often true than not -- now they have to go and find a list of all members of that package in order to have some idea of what's being added to the namespace. With the current situation, you can see the names of modules being imported, and so have (more likely at least) some idea of what's being put into the namespace. 2 - Depth ambiguity. Given a package structure: /mylib/alpha.d /mylib/beta.d /mylib/utils/mercurius.d /mylib/utils/venus.d And given the import statement: import mylib .* ; What has been imported? Or in other words, is the 'utils' subpackage included in this sweeping import? Or must sub-packages be imported independantly? (Yes, yes, of course an implementation would state this in stone somewhere... but imagine the debates needed to decide the course of that implementation.) 3 - Pollution. If you need three modules out of a package of thirty, do you really want to put up with all the potential symbol collisions from a bunch of cruft you aren't even using?? Do you want to have to but that dangling dot (module scope specifier) in front of your local symbols just to disambiguate them from functions you never call, or classes you never instantiate, etc etc etc? I know I sure as heck don't. 4 - Aesthetics. Call me weird, and note I have done some work in Java, but I just plain don't like the look of the .* syntax for some reason. :) -- Chris Nicholson-Sauls
Dec 11 2006
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Chris Nicholson-Sauls wrote:
 Trevor Parscal wrote:
 Why not just use

 import package.*;

 it makes sense in regexp statements, it works for java, why not use it 
 here?
 What's the problem?

Problems:

I agree that * is not so hot. I don't know about in Java circles, but at least in the Python world using "import foo.*" is generally frowned upon for anything other than use at the interactive prompt to save some typing. But there is a real need, I think, for a more compact syntax for importing several modules deep down in a package hierarchy. import somebodys.long.package.name.module1; import somebodys.long.package.name.module2; import somebodys.long.package.name.module3; just doesn't look so slick. This is exactly the same issue that got debated endlessly regarding individual symbols, which resulted eventually in the syntax import somebodys.long.package.name.module1 : sym1,sym2,sym3; except now we're talking about it at the module level rather than the symbol level. Personally, I think the solution should be to allow things like: import somebodys.long.package.name : module1, module2, module3; and maybe also import somebodys.long.package.name : module1.sym1, module2.sym2; maybe even import somebodys.long.package.name : (module1:sym1), (module2:sym2); But I think at least the first one should work. --bb
Dec 11 2006
next sibling parent reply Xinok <xnknet gmail.com> writes:
import package.sub_package.vendor.[module_a.[sub1, sub2], module_b];
I think this can quickly become messy and difficult to read.

I have an idea, "virtual import". A virtual import doesn't actually import any
modules, it only imports a symbol:
virtual import package.sub_package.vendor;
import vendor.module_a.sub1;
import vendor.module_b.sub2;
import vendor.module_b;


The first problem though is this can easily cause naming collisions:
module std.stdio;
module std.c.stdio;

virtual import std, std.c;
import stdio; // Import std.stdio or std.c.stdio?


So perhaps defining an alias would work best:
virtual import mod : package.sub_package.vendor;
import mod.module_a.sub1, mod.module_a.sub2, mod.module_b;
Dec 11 2006
parent reply janderson <askme me.com> writes:
Xinok wrote:

 So perhaps defining an alias would work best:
 virtual import mod : package.sub_package.vendor;
 import mod.module_a.sub1, mod.module_a.sub2, mod.module_b;

What about: alias package.sub_package.vendor mod; import mod.module_a.sub1; import mod.module_a.sub2; import mod.module_b; ?
Dec 11 2006
parent reply Tom Johnson <tjohnson prtsoftware.com> writes:
janderson wrote:
 Xinok wrote:
 
 So perhaps defining an alias would work best:
 virtual import mod : package.sub_package.vendor;
 import mod.module_a.sub1, mod.module_a.sub2, mod.module_b;

What about: alias package.sub_package.vendor mod; import mod.module_a.sub1; import mod.module_a.sub2; import mod.module_b; ?

What about using something like the With statement? Some possible examples: with package.sub_package.vendor { import module_a.sub1; import module_a.sub2; import module_b; } with package.sub_package.vendor { with module_a { import sub1; import sub2; } import module_b; } -- Tom J import module_a.sub2; import module_b; }
Dec 11 2006
parent reply "Tomas Lindquist Olsen" <tomas famolsen.dk> writes:
Tom Johnson wrote:

 janderson wrote:
 Xinok wrote:
 
 So perhaps defining an alias would work best:
 virtual import mod : package.sub_package.vendor;
 import mod.module_a.sub1, mod.module_a.sub2, mod.module_b;

What about: alias package.sub_package.vendor mod; import mod.module_a.sub1; import mod.module_a.sub2; import mod.module_b; ?

What about using something like the With statement? Some possible examples: with package.sub_package.vendor { import module_a.sub1; import module_a.sub2; import module_b; } with package.sub_package.vendor { with module_a { import sub1; import sub2; } import module_b; } -- Tom J import module_a.sub2; import module_b; }

Or what about: import(package.sub_package) { import(module_a) { import sub1; } }
Dec 11 2006
parent reply Alexander Panek <a.panek brainsware.org> writes:
Bloooat. :\

Tomas Lindquist Olsen wrote:
 What about using something like the With statement?

 Some possible examples:

 with package.sub_package.vendor {
   import module_a.sub1;
   import module_a.sub2;
   import module_b;
 }

 with package.sub_package.vendor {
   with module_a {
      import sub1;
      import sub2;
   }
   import module_b;
 }

 -- Tom J

   import module_a.sub2;
   import module_b;
 }

Or what about: import(package.sub_package) { import(module_a) { import sub1; } }

Dec 11 2006
next sibling parent "Tomas Lindquist Olsen" <tomas famolsen.dk> writes:
Alexander Panek wrote:

 Bloooat. :\

:) Actually I agree and I don't really see why we need this at all... I dont mind copy/pasting the imports...
Dec 11 2006
prev sibling parent "John Reimer" <terminal.node gmail.com> writes:
On Mon, 11 Dec 2006 23:57:34 -0800, Alexander Panek  
<a.panek brainsware.org> wrote:

 Bloooat. :\

Ack... all these solutions are ugly. I think "wait and see" is good enough for now. :) -JJR
Dec 12 2006
prev sibling parent reply Alexander Panek <a.panek brainsware.org> writes:
 import somebodys.long.package.name.module1 : sym1,sym2,sym3;

That's what came to my mind, too. Though, I wouldn't use the ':' operator. // might be hard to parse (?) - at least it's clear what's meant (imho) import somebodys.long.package.name.a, .b, .c; // might be confused with /+ import foo, bar; +/ import somebodys.long.package.name.a, b, c; analog to: uint a, b, c; ...just that the type is exchanged with a module/package path. Other than that, I don't think one should make the import syntax too blown up. Also, I would restrict multiple module import to one path per statement, so you don't end up doing nested regex magic in your import statements. I think of something like import a.b.[c.[a,b,d.e], f, g] .. huh? Now guess what happens when you don't use single characters as module names only. :P import a.b.c.a, .b, .d, .e; import a.b.f, .g; I'd like to have it like that. Kind regards, Alex
Dec 11 2006
parent Alexander Panek <a.panek brainsware.org> writes:
Alexander Panek wrote:
 
 import somebodys.long.package.name.module1 : sym1,sym2,sym3;

That's what came to my mind, too. Though, I wouldn't use the ':' operator.

Sorry, misunderstood that one X_X
Dec 11 2006