www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Entity naming revised

reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
The following post is about entity naming and scoping, i.e. how entities 
are accessed and made available. This is a reworked follow-up after the 
original discussion on this previous thread: 
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/28105 .

BACKGROUND TERMINOLOGY:

In D (and similar programming languages), I define the term "entity" as: 
a code entity that can be defined and named (this is not a recursive 
definition btw). That would be: variables, classes (and template 
instances), structs, typedefs, functions, enums, enum literals, modules, 
etc.. Labels too but nevermind them. Aliases are a special entity case. 
Packages currently aren't proper entities, they are instead part of the 
module base name (more on this below).

A scoping entity is an entity that introduces a new scope, in which new 
entities can be defined. Most entities are scoping entities.
An entity can be refered by it's base name, if available in the current 
scope, or (recursively) trough it's parent scoping entity with the "." 
operator, if the parent entity is available in the current scope (and if 
security and semantic restrictions allow it). Example:

   module packA.foobar;

   class Foo{
     static int var1 = 42;
     this() {
       // packA.foobar.Foo.var1 entity accessed by base name:
       int var2 = var1;
     }
   }

   void func() {
     // packA.foobar.Foo.var1 entity accessed by parent Foo:
     Foo.var1++;
   }

Thus an entity can be access/used/refered by several names.
The Fully Qualified Name of an entity is it's base name plus all parent 
entities names in its hierarchy. Example: packA.foobar.Foo.var1 . The 
FQN is unique.


CURRENT SITUATION:

Currenly, external entities are made accessible by the import <module>; 
statement. This statement processes the imported module and then does 
two things:
1) It brings the <module> entity to the current module scope.
2) It brings all entities in the <module> scope to the current module scope.
There is a security attribute in an import (public or private) that 
specifies the visibility of the imported entities when the current 
module is imported elsewhere. The default is public (i.e. propagate 
imports).

Problems/shortcomings:

1) It is conceptualy wrong to have this statement make entities 
acessible in two ways, since almost allways you will want to use only 
one way. It is especially worse when it is by FQN that you want to 
access the module's entities, as the unwanted base names start polluting 
the current module scope. In this situation, a more concrete problem 
arises for example when you have an IDE with code autocompletion.
2) You cannot import two modules that have each a (public) child entity 
with the same name. There is no workaround for this. [I think...]
3) The default behaviour of import is to do a public import, but private 
imports are by far more common. [are they not? In a test project of 
mine, and in some random source files of some projects I've looked up on 
dsource.org, *all* imports I saw were private]

I am pretty damn sure that the behaviour of this whole aspect is 
ill-conceived and needs to be rethinked and fixed.


PROPOSALS:
Here is a set of three sequential proposals (i.e. should be implemented 
only after the previous), plus a forth parallel proposal. They are not 
final, i.e. some points are still open to discussion.


PROPOSAL 1, FQN import:
Introduce a new statement, identical to import, :
   fqnimport <module>;
except that it only brings the <module> entity into scope. It's child 
entities will have to be accessed trough the <module> entity (by FQN then).
The keyword for this statement could be "fqnimport", or perhaps a 
shorter but still descriptive name like "mimport", "importm" (for import 
module)? [Right now I'm favoring "importm" but am not decided;]


PROPOSAL 2, import scopes statement(using):
Introduce a new statement, the using statement, that would import 
another entity's scope into the current scope. Usage:
   using <scoping entity>;
where scoping entity would be a module. Ideally the statement should be 
allowed on any block, not just at module-scope level. Also, the 
behaviour of using is pretty much the same as the with statement, only 
that this later has a different form:
   with ( <scoping entity or expression> ) /BlockStatement/
Thus it would be better if using was a generalization of the with 
statement, and to also allow it to have the same form as with, as well 
as allow the scoping entities (or expressions) allowed in with.

* Variant 1:
Should using also allow packages as a scoping entity? For example:

   importm renderer.foo;
   importm renderer.bar;
   importm renderer.baz;
   using renderer;
   ...
     bar.doStuff();

This does seems to make sense and be useful. However one must first ask 
what exactly a package is. Conceptualy it is clear that it is a 
collection of modules and sub-packages. However, in (D) code, how is 
then a package *defined*? Such package definition could the one 
extracted from the tree of packages&modules created by the import(and 
importm) statements so far. The problem is this "so far"... consider this:

   importm renderer.foo;
   importm renderer.bar;
   using renderer;
   importm renderer.baz;

Would baz be accessible? The problem is that packages cant be 
well-defined, or more precisely, to be defined in just one statement . 
Should "using renderer;" consider the tree created by only the previous 
import statements, or by the next imports as well?
I think this would be implementation defined, and considered bad code 
style; Also, proposal 3 offers a proper [and preferable IMO] solution to 
this.


PROPOSAL 3, Automatic Availability of all Entities by FQN:
Automatically search for all D source files in a given path (called the 
import path), specified in the command-line to the compiler, and 
fqn-import all such D files. The fqnimport statement (with the keyword 
"importm" or other) would then be ignored (and become deprecated). The 
normal import statement would do the same as the using statement (and 
become deprecated).

This is the most radical of the proposed changes, but overall this is a 
better conceptual and semantic approach for the whole naming 
environment. In pratice, besides removing the needless need for 
fqn-imports, it also has some other advantages and possibilities I can 
think of. One of them is that it well-defines the package entity, since 
packages would be defined instantly and have the same definition 
everywhere, and thus better suited for use (by using statements).
Sidenote: This feature can be somewhat emulated once you have the 
fqn-import statement, on a project basis by an external tool (the tool 
adds fqn-imports for all modules before compilation). However it has 
some natural shortcomings, and so it is only a second-best option to 
being a built-in language feature.

Compatibility:
There would be errors if a top-level package or module would have the 
same name as an entity defined in the current module scope. A workaround 
could be made I think, if one was interested in preserving full 
backwards compatibility.


PROPOSAL 0, private as default import visibility:
Since private imports are far more common than public imports, private 
should be the default visibility/security of the imported entities in 
whatever kind of import statement (normal import, fqn-import, using).

Compatibility:
Backwards compatibility would not be garanteed. Any program that used 
public imports might become broken, altough in a simple-to-fix way. (One 
could garantee backwards compatibility if only the new import statements 
(using, fqn-import) were changed to this behaviour)


- - - -

Pheew.., I'm fatigued from all this writing... :p

-- 
Bruno Medeiros
Computer Science/Engineering student
Sep 06 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 07 Sep 2005 00:31:49 +0000, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:
<snip>

Nice post. I agree with much of what you say.

 Problems/shortcomings:

 1) It is conceptualy wrong to have this statement make entities  
 acessible in two ways, since almost allways you will want to use only  
 one way. It is especially worse when it is by FQN that you want to  
 access the module's entities, as the unwanted base names start polluting  
 the current module scope. In this situation, a more concrete problem  
 arises for example when you have an IDE with code autocompletion.
I find collisions in symbol names a pain (heck even phobos has these issues) and the alias workaround annoying. I see "import" as being redundant (except perhaps as documentation) in the case where you use FQN's. Collisions I've encountered in Phobos: std.string and std.regexp 'find' std.c.stdio and std.stream 'stdin'
 2) You cannot import two modules that have each a (public) child entity  
 with the same name. There is no workaround for this. [I think...]
There is a workaround, "alias" eg. [mod1.d] int foo; [mod2.d] double foo; [main.d] import mod1; import mod2; alias mod2.foo foo; void main() { foo = 5.5; }
 3) The default behaviour of import is to do a public import, but private  
 imports are by far more common. [are they not? In a test project of  
 mine, and in some random source files of some projects I've looked up on  
 dsource.org, *all* imports I saw were private]
I agree. Imports should be private by default. The most common argument against this is that everything else is public by default (i.e. class members) so it's consistent. To which I reply, you're comparing apples and oranges and expect them to be consistent (i.e. the same)? madness! <snip>
 PROPOSAL 3, Automatic Availability of all Entities by FQN:
 Automatically search for all D source files in a given path (called the  
 import path), specified in the command-line to the compiler, and  
 fqn-import all such D files. The fqnimport statement (with the keyword  
 "importm" or other) would then be ignored (and become deprecated). The  
 normal import statement would do the same as the using statement (and  
 become deprecated).

 This is the most radical of the proposed changes, but overall this is a  
 better conceptual and semantic approach for the whole naming  
 environment. In pratice, besides removing the needless need for  
 fqn-imports, it also has some other advantages and possibilities I can  
 think of. One of them is that it well-defines the package entity, since  
 packages would be defined instantly and have the same definition  
 everywhere, and thus better suited for use (by using statements).
 Sidenote: This feature can be somewhat emulated once you have the  
 fqn-import statement, on a project basis by an external tool (the tool  
 adds fqn-imports for all modules before compilation). However it has  
 some natural shortcomings, and so it is only a second-best option to  
 being a built-in language feature.

 Compatibility:
 There would be errors if a top-level package or module would have the  
 same name as an entity defined in the current module scope. A workaround  
 could be made I think, if one was interested in preserving full  
 backwards compatibility.
I'd vote for "PROPOSAL 3" entities should be available by FQN without any import style statement. However, I don't understand why "using" or "import" would be deprecated? I think we still need a statement which says "bring this module into the current scope". "import" is that statement, further "alias" would not change in behaviour and would be required to resolve the collisions created by "import". This would mean that "import" and "alias" enable shorthand, thay are tools to lessen the amount of typing we need to do. Another potentially useful idea is to have a statement, say "using" which does what import does but only after the line on which it appears, eg. using a; foo = 5; <- could be foo or a.foo using b; foo = 6; <- could be foo, a.foo or b.foo
 PROPOSAL 0, private as default import visibility:
 Since private imports are far more common than public imports, private  
 should be the default visibility/security of the imported entities in  
 whatever kind of import statement (normal import, fqn-import, using).
Agreed. Regan
Sep 06 2005
parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Regan Heath wrote:
 On Wed, 07 Sep 2005 00:31:49 +0000, Bruno Medeiros  
 2) You cannot import two modules that have each a (public) child 
 entity  with the same name. There is no workaround for this. [I think...]
There is a workaround, "alias" eg. [mod1.d] int foo; [mod2.d] double foo; [main.d] import mod1; import mod2; alias mod2.foo foo; void main() { foo = 5.5; }
Indeed, seems I missed that one.
 3) The default behaviour of import is to do a public import, but 
 private  imports are by far more common. [are they not? In a test 
 project of  mine, and in some random source files of some projects 
 I've looked up on  dsource.org, *all* imports I saw were private]
I agree. Imports should be private by default. The most common argument against this is that everything else is public by default (i.e. class members) so it's consistent. To which I reply, you're comparing apples and oranges and expect them to be consistent (i.e. the same)? madness!
Agreed, the comparision is senseless. I would even go as far as saying that public imports might not be needed at all, especially if you have auto import (proposal 3). In fact that's the case with modern languages
 
 I'd vote for "PROPOSAL 3" entities should be available by FQN without 
 any  import style statement.
 
 However, I don't understand why "using" or "import" would be deprecated? 
 I  think we still need a statement which says "bring this module into 
 the  current scope". "import" is that statement, further "alias" would 
 not  change in behaviour and would be required to resolve the 
 collisions  created by "import".
 
 This would mean that "import" and "alias" enable shorthand, thay are 
 tools  to lessen the amount of typing we need to do.
 
 Another potentially useful idea is to have a statement, say "using" 
 which  does what import does but only after the line on which it 
 appears, eg.
 
 using a;
 
 foo = 5; <- could be foo or a.foo
 
 using b;
 
 foo = 6; <- could be foo, a.foo or b.foo
 
I agree, and I didn't meant to say using should be deprecated. In this sentence: "The normal import statement would do the same as the using statement (and become deprecated)." , when I said become deprecated I was only refering to the normal import statement, not using. -- Bruno Medeiros Computer Science/Engineering student
Sep 07 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 07 Sep 2005 11:00:48 +0000, Bruno Medeiros  
<daiphoenixNO SPAMlycos.com> wrote:
<snip>

  I'd vote for "PROPOSAL 3" entities should be available by FQN without  
 any  import style statement.
  However, I don't understand why "using" or "import" would be  
 deprecated?
<snip>
 I agree, and I didn't meant to say using should be deprecated. In this  
 sentence: "The normal import statement would do the same as the using  
 statement (and  become deprecated)." , when I said become deprecated I  
 was only refering to the normal import statement, not using.
Ahh.. I see now. In that case I vote for "PROPOSAL 3". Regan
Sep 07 2005
prev sibling next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 Currenly, external entities are made accessible by the import <module>; 
 statement. This statement processes the imported module and then does two 
 things:
 1) It brings the <module> entity to the current module scope.
 2) It brings all entities in the <module> scope to the current module 
 scope.
 There is a security attribute in an import (public or private) that 
 specifies the visibility of the imported entities when the current module 
 is imported elsewhere. The default is public (i.e. propagate imports).

 Problems/shortcomings:

 1) It is conceptualy wrong to have this statement make entities acessible 
 in two ways, since almost allways you will want to use only one way.
Given 2 above most D code I've seen uses the short name with occasional FQN or aliases. Similarly most Java code I've seen uses the short names. As you've posted earlier your style is different so I'd just avoid using short names and always use the FQN - what you don't use won't hurt you :-)
 It is especially worse when it is by FQN that you want to access the 
 module's entities, as the unwanted base names start polluting the current 
 module scope.
I'm not sure what the problem is. Can you give an example? Any definition in the current module scope hides the imported entities.
 In this situation, a more concrete problem arises for example when you 
 have an IDE with code autocompletion.
I don't understand. Can you give more details?
 2) You cannot import two modules that have each a (public) child entity 
 with the same name. There is no workaround for this. [I think...]
I don't understand the problem. This works fine: module f1; int x; module f2; int x; module f3; import f1, f2; int main() { f1.x = 10; f2.x = 20; return 0; }
 3) The default behaviour of import is to do a public import, but private 
 imports are by far more common. [are they not? In a test project of mine, 
 and in some random source files of some projects I've looked up on 
 dsource.org, *all* imports I saw were private]
This is a reasonable request that I wouldn't have a problem with. Switching the default visiblity would be pretty simple and easy to modify user code. I'm sure you've read all the previous threads about this since it has come up before. I don't mind the current behavior but then I've gotten used to typing "private" before most of my imports.
Sep 06 2005
parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Ben Hinkle wrote:
Currenly, external entities are made accessible by the import <module>; 
statement. This statement processes the imported module and then does two 
things:
1) It brings the <module> entity to the current module scope.
2) It brings all entities in the <module> scope to the current module 
scope.
There is a security attribute in an import (public or private) that 
specifies the visibility of the imported entities when the current module 
is imported elsewhere. The default is public (i.e. propagate imports).

Problems/shortcomings:

1) It is conceptualy wrong to have this statement make entities acessible 
in two ways, since almost allways you will want to use only one way.
Given 2 above most D code I've seen uses the short name with occasional FQN or aliases. Similarly most Java code I've seen uses the short names. As you've posted earlier your style is different so I'd just avoid using short names and always use the FQN - what you don't use won't hurt you :-)
There is something else I must clarify. In theoretical terms it's not just by base name or FQ name that you can access a variable, it could be starting in the middle of the hierarchy. And so, what I actually want is not necessarily to access by FQN, but instead to access entities (not all btw) with at least *one* parent entity, one that specifies the "category", the conceptual module/part of the program. This may be the FQN if the FQN is short, but it can be only part of it. That explained, I must contest that this style I've just described is that different or uncommon: In D you don't have the facilities to work with this unobtrusively (you would have to use aliases). That's why I talked about allowing packages in the using statement). short names" (I'm assuming you mean base names). Because if you have a set of functions and variables you wish to group together, in Java you must encase them in a class as static members (or as normal members of a singleton class), and so when they are accessed they will allways have at least that class as a prefix.
It is especially worse when it is by FQN that you want to access the 
module's entities, as the unwanted base names start polluting the current 
module scope.
I'm not sure what the problem is. Can you give an example? Any definition in the current module scope hides the imported entities.
In this situation, a more concrete problem arises for example when you 
have an IDE with code autocompletion.
I don't understand. Can you give more details?
An example from the previous thread, slighty modified: As for the IDE code-completion, to be more clear let me give an example of what would happen with D currently: module foobar; void DoStuff() { ... } void DoStuff2() { ... } --------------------------------------- module whatever; import foobar; void DoThings() { ... } void DoMoreThings() { ... } int func(){ ... Do| <- press ctrl-space here for code-completion } In this example you want to access entities from foobar by FQN, such as foobar.DoStuff() . However, the base name (DoStuff, DoStuff2, etc.) of the entities of foobar is also made availabe in the current module scope by the import. So when you want to use code-completion, (in this example with the cursor right after Do where the "|" symbol is), you will be presented the the local options (DoThings, DoMoreThings), plus DoStuff and DoStuff2, which you do not want to be presented.
2) You cannot import two modules that have each a (public) child entity 
with the same name. There is no workaround for this. [I think...]
I don't understand the problem. This works fine: module f1; int x; module f2; int x; module f3; import f1, f2; int main() { f1.x = 10; f2.x = 20; return 0; }
Yes, I was wrong, I was thinking that the clash ocurred only when you tried to use the conflicting var, not just by importing.
3) The default behaviour of import is to do a public import, but private 
imports are by far more common. [are they not? In a test project of mine, 
and in some random source files of some projects I've looked up on 
dsource.org, *all* imports I saw were private]
This is a reasonable request that I wouldn't have a problem with. Switching the default visiblity would be pretty simple and easy to modify user code. I'm sure you've read all the previous threads about this since it has come up before. I don't mind the current behavior but then I've gotten used to typing "private" before most of my imports.
If those threads are from some time ago, I probably haven't seen them since I'm still new around here. And now that you say that, it worries me that there have been some threads about this previously and nothing has changed :( . Where there many people who disagreed with such change? Or just Walter? -- Bruno Medeiros Computer Science/Engineering student
Sep 07 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
In this situation, a more concrete problem arises for example when you 
have an IDE with code autocompletion.
I don't understand. Can you give more details?
An example from the previous thread, slighty modified: As for the IDE code-completion, to be more clear let me give an example of what would happen with D currently: module foobar; void DoStuff() { ... } void DoStuff2() { ... } --------------------------------------- module whatever; import foobar; void DoThings() { ... } void DoMoreThings() { ... } int func(){ ... Do| <- press ctrl-space here for code-completion }
The IDE can have a preference to toggle between showing all symbols and symbols in the current module. By default it would show everything (since that's how D works normally) but if one wants to only work with local symbols one can restrict what gets shown.
Sep 07 2005
parent Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Ben Hinkle wrote:
In this situation, a more concrete problem arises for example when you 
have an IDE with code autocompletion.
I don't understand. Can you give more details?
An example from the previous thread, slighty modified: As for the IDE code-completion, to be more clear let me give an example of what would happen with D currently: module foobar; void DoStuff() { ... } void DoStuff2() { ... } --------------------------------------- module whatever; import foobar; void DoThings() { ... } void DoMoreThings() { ... } int func(){ ... Do| <- press ctrl-space here for code-completion }
The IDE can have a preference to toggle between showing all symbols and symbols in the current module. By default it would show everything (since that's how D works normally) but if one wants to only work with local symbols one can restrict what gets shown.
What makes you think one will want to work the same way (by local names or FQN) with all entities? That is certainly not the case. And so, consider the following where one uses 3 ways to access entities: module whatever; import xpto; // wants acces by FQN import misc; // wants access by base/local name; import foobars.foobarA; // wants access by "middle" name; alias foobars.foobarA foobarA; // bad hack for "using" packages. ... xpto.doStuff // xpto.doStuff something // misc.something foobarA.doStuff // foobars.foobarA.doStuff The IDE code completion will be filled with clutter of other access pathways. Granted, the third way (/using/ hack) may not be very common, but the other two will, and still mess up the IDE. -- Bruno Medeiros Computer Science/Engineering student
Sep 08 2005
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <dflce3$21vp$1 digitaldaemon.com>, Bruno Medeiros says...
1) It is conceptualy wrong to have this statement make entities 
acessible in two ways, since almost allways you will want to use only 
one way. It is especially worse when it is by FQN that you want to 
access the module's entities, as the unwanted base names start polluting 
the current module scope.
But sometimes you want the base names to pollute the module's scope. An obvious example are the standard C and POSIX headers. Many of them are required to expose symbols defined in other modules. Since private import/alias doesn't work (it's seen as a re-declaration from importing modules), public import is the only option. I like your suggestions, but there must be a way to import one module's symbols into another, even if it is explicit (through 'using', for example). Sean
Sep 07 2005
next sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <dfmvr0$drb$1 digitaldaemon.com>, Sean Kelly says...
In article <dflce3$21vp$1 digitaldaemon.com>, Bruno Medeiros says...
1) It is conceptualy wrong to have this statement make entities 
acessible in two ways, since almost allways you will want to use only 
one way. It is especially worse when it is by FQN that you want to 
access the module's entities, as the unwanted base names start polluting 
the current module scope.
But sometimes you want the base names to pollute the module's scope. An obvious example are the standard C and POSIX headers. Many of them are required to expose symbols defined in other modules. Since private import/alias doesn't work (it's seen as a re-declaration from importing modules), public import is the only option. I like your suggestions, but there must be a way to import one module's symbols into another, even if it is explicit (through 'using', for example).
This got me thinking. What if we keep the behavior of import, but allow for a more verbose syntax when we want less generalized behavior.
 import <module> as <namespace name>
It would function along the lines of the current guidelines for aliasing module definitions, but it would affect the entire import. Plus, we could define this as saying that all the symbols imported this way *must* use the FQN prefixed by the 'namespace name' provided.
 module foobar;
 void DoSomething(){}
 module whatever;
 import foobar as foobar;
 import foobar as gorf;

 void main(){
   foobar.DoSomething();
   gorf.DoSomething(); // technically the same thing
   DoSomething(); // illegal, does not exist as 'DoSomething()' is not in scope
 }
So by this we get a short-but-sweet workaround to namespace concflicts. Personally, I think something like this would dovetail nicely with D's current behavior. It also has the benefit of not breaking all the code that's already being maintained. The 'as' token isn't presently a keyword, but AFAIK not many programmers use it as a variable or function name anyway. At worst, 'as' could be replaced by another token like 'is' or '=', without changing the overall semantics of this proposal.
 import foobar is foobar;
 import foobar = foobar;
Does this solve the problem at hand? - EricAnderton at yahoo
Sep 07 2005
next sibling parent Sean Kelly <sean f4.ca> writes:
In article <dfn1j0$fd4$1 digitaldaemon.com>, pragma says...
This got me thinking.  What if we keep the behavior of import, but allow for a
more verbose syntax when we want less generalized behavior.

 import <module> as <namespace name>
It would function along the lines of the current guidelines for aliasing module definitions, but it would affect the entire import. Plus, we could define this as saying that all the symbols imported this way *must* use the FQN prefixed by the 'namespace name' provided.
..
Does this solve the problem at hand?
While a finer-grained control of symbol visibility would be nice, this suggestion seems like a good compromise. And since the mixin syntax already works this way (I think), extending it to import seems appropriate. Sean
Sep 08 2005
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
pragma wrote:
 This got me thinking.  What if we keep the behavior of import, but allow for a
 more verbose syntax when we want less generalized behavior.
 
 
import <module> as <namespace name>
It would function along the lines of the current guidelines for aliasing module definitions, but it would affect the entire import. Plus, we could define this as saying that all the symbols imported this way *must* use the FQN prefixed by the 'namespace name' provided.
I can see a bit of usefullness for that feature, but not as a replacement for a fqn-import statement. Why? Because the equivalent import-as to a fqn-import statement is tediously unnecessarily longer to write: importm foobars.foobarABC; vs. import foobars.foobarABC as foobars.foobarABC; -- Bruno Medeiros Computer Science/Engineering student
Sep 08 2005
parent reply pragma <EricAnderton youknowthedrill.yahoo> writes:
Bruno Medeiros wrote:
 pragma wrote:
 
 This got me thinking.  What if we keep the behavior of import, but 
 allow for a
 more verbose syntax when we want less generalized behavior.


 import <module> as <namespace name>
It would function along the lines of the current guidelines for aliasing module definitions, but it would affect the entire import. Plus, we could define this as saying that all the symbols imported this way *must* use the FQN prefixed by the 'namespace name' provided.
I can see a bit of usefullness for that feature, but not as a replacement for a fqn-import statement. Why? Because the equivalent import-as to a fqn-import statement is tediously unnecessarily longer to write: importm foobars.foobarABC; vs. import foobars.foobarABC as foobars.foobarABC;
Granted, but that's just *once* for the import statement. Since adopting this form would lock you into using an FQN for every member of the imported module, it's not the last time you're going to type that out. ;) Also, there's no reason why you can't just abbreviate the module name, along the lines of what's been proposed by using alias statement workarounds:
 import foobars.foobarABC as foobarABC;
-- - EricAnderton at yahoo
Sep 08 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 08 Sep 2005 19:28:31 -0700, pragma wrote:

Hey Eric, you want to check your computer's clock setting? You posts arrive
about 13 hours into the future.

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
9/09/2005 9:34:03 AM
Sep 08 2005
parent pragma <EricAnderton youknowthedrill.yahoo> writes:
Derek Parnell wrote:
 On Thu, 08 Sep 2005 19:28:31 -0700, pragma wrote:
 
 Hey Eric, you want to check your computer's clock setting? You posts arrive
 about 13 hours into the future.
 
Heh, thanks for letting me know Derek. :) Looks like my settins were in the wrong timezone. -- - EricAnderton at yahoo
Sep 09 2005
prev sibling parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Sean Kelly wrote:
 In article <dflce3$21vp$1 digitaldaemon.com>, Bruno Medeiros says...
 
1) It is conceptualy wrong to have this statement make entities 
acessible in two ways, since almost allways you will want to use only 
one way. It is especially worse when it is by FQN that you want to 
access the module's entities, as the unwanted base names start polluting 
the current module scope.
But sometimes you want the base names to pollute the module's scope. An obvious example are the standard C and POSIX headers. Many of them are required to expose symbols defined in other modules. Since private import/alias doesn't work (it's seen as a re-declaration from importing modules), public import is the only option. I like your suggestions, but there must be a way to import one module's symbols into another, even if it is explicit (through 'using', for example). Sean
Are you sure you quoted the right paragraph? I'm not sure about what and which of two different things you are talking about: If either about the base-import vs fqn-import (and the fact that currently one cannot do one of them separately from the other, and thus the "polution"), or about private imports vs public imports. And what exactly is it that "there must be a way to", but you can't do on my suggestions? -- Bruno Medeiros Computer Science/Engineering student
Sep 08 2005
parent Sean Kelly <sean f4.ca> writes:
In article <dfqg3h$jqu$1 digitaldaemon.com>, Bruno Medeiros says...
Sean Kelly wrote:
 In article <dflce3$21vp$1 digitaldaemon.com>, Bruno Medeiros says...
 
1) It is conceptualy wrong to have this statement make entities 
acessible in two ways, since almost allways you will want to use only 
one way. It is especially worse when it is by FQN that you want to 
access the module's entities, as the unwanted base names start polluting 
the current module scope.
But sometimes you want the base names to pollute the module's scope. An obvious example are the standard C and POSIX headers. Many of them are required to expose symbols defined in other modules. Since private import/alias doesn't work (it's seen as a re-declaration from importing modules), public import is the only option. I like your suggestions, but there must be a way to import one module's symbols into another, even if it is explicit (through 'using', for example).
Are you sure you quoted the right paragraph? I'm not sure about what and which of two different things you are talking about: If either about the base-import vs fqn-import (and the fact that currently one cannot do one of them separately from the other, and thus the "polution"), or about private imports vs public imports. And what exactly is it that "there must be a way to", but you can't do on my suggestions?
Nothing :) I merely didn't want this necessity to be overlooked. For what it's worth, I like Eric's suggestion the best. That is, to allow for an optional namespace specifier on import statements (similar to mixins): import mod mod_a; import mod mod_b; I like the the suggestion of 'as', but then the mixin syntax should be changed as well. This offers all the features of your Proposal 2 (which I liked the best of the four) but keeps default behavior unchanged, which I think is important. Also, I'm not sure I like the impact that an abbreviated namespace system would have on D. It would really have to be all or nothing to keep from being unwieldy, and I like D's visibility rules better than those in C++. Sean
Sep 08 2005
prev sibling next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bruno Medeiros" <daiphoenixNO SPAMlycos.com> wrote in message 
news:dflce3$21vp$1 digitaldaemon.com...
 I am pretty damn sure that the behaviour of this whole aspect is 
 ill-conceived and needs to be rethinked and fixed.
This sounds like a job for namespacing. [module1.d] module module1; namespace foo // explicit namespace - MUST use FQN { int bar; } [main.d] import module1; import std.stdio; void main() { writefln(foo.bar); writefln(bar); // Illegal, must use FQN } Or, perhaps some anonymous namespaces... [module1.d] module module1; namespace // anonymous namespaces take namespace of module { int foo; } int bar; [main.d] import module1; import std.stdio; void main() { writefln(module1.foo); writefln(foo); // illegal, must use FQN writefln(module1.bar); writefln(bar); // OK, bar is not in explicit module namespace // is imported into current namespace } Namespaces could also be more useful by allowing them in classes, when using inner classes or structs is too overkill (or just not an option, i.e. if you want to derive from a class and overload the methods of an inner class or struct, it's impossible, but it would be possible with a namespace's methods).
Sep 08 2005
prev sibling parent Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Well, I still didn't got Walter's view on this issue. There is little 
more I can say other than restate that the shortcomings of the current 
situation.
So heed these words, this will either be fixed in time, or it will haunt 
D until so.


-- 
Bruno Medeiros
Computer Science/Engineering student
Sep 12 2005