July 11, 2006
John Reimer wrote:
> 
> "Walter Bright" <newshound@digitalmars.com> wrote in message news:e8utvp$53$1@digitaldaemon.com...
>> John Reimer wrote:
>>> If you can find something
>>> equivalent to from/as (which you most certainly haven't), without adopting new
>>> syntax, maybe we'll bite... but so far, I think using 'with' (or from) and 'as'
>>> is an excellent contender.
>>
>> I'll repeat myself here, too <g>. The 'static import' combined with 'alias' has
>>
>> *exactly the same semantics*
>>
>> as 'with' 'as'. The only difference between the proposals is if there are two statements or one. There is no difference in power or effect. There is nothing that one can do that the other cannot.
>>
> 
> 
> The semantics are not exactly the same.  Read Sean and Kris's explanations again, please.  'static import' adds nothing to the what this whole namespace business.  It just sharpens the compiler a bit to enforce FQN for the programmer's sake.  But that is absolutely unnecessary because a D programmer that wants to do that now can just make sure he uses FQNs!  So what's the point of 'static import'?

I have to disagree with this. Currently, suppose you have a module that uses the toString() functions from std.string (and uses them hundreds of times). Then, you decide you need to use std.date in one place to get the current time. Suddenly, your module won't compile, because std.date.toString() conflicts with all the other toString()s that you're using. Even though you're not even using std.date.toString !

With the static import proposal, you could just have

import std.string;
static import std.date;

and then use FQNs for the single usage of date.

This is not a contrived example, I encountered it in my second D program (and I immediately thought that there were serious problems with the D module system. You're telling me I have to alias std.string.toString just because I want to use std.date.getUTCtime() ???). 'static import' would make it possible to avoid the use of FQNs in most cases; it would enable you to distinguish 'I'm going to use a function from this module' (static import) from 'I'm heavily depending on this module' (normal import).

Which is not to say that I'm favouring 'static import' in this discussion, I'm simply saying that all of the proposals, including static import, are an *enormous* improvement over what we have now.
July 11, 2006
Walter Bright wrote:
> Dave wrote:
>> Walter, I think what most are getting at here is that the 'as' syntax just seems cleaner and more efficient from a coding and maintenance POV.
>>
>> If it's easy to implement, then I say go for it. If nothing else, people can still use 'explicit' aliasing. I argue that 'as' will actually be quicker for newbies to grasp (*especially* when they see it in example code), and my sense is that it will be a boon to maintenance because it generally won't end-up buried in the middle of a module like many aliases would be. It's not like alias will be a wasted feature - most prominently it will be used for storage types; it just feels more 'natural' that way.

(I'm pretty tired so forgive me for being succinct/unclear)

> I think you're saying that this is not a discussion about functionality, but about aesthetics. I agree with that.
> 
> A couple of people have brought up the alias-in-the-middle thing:
> 
> 1) If it's in the middle because it's in a nested scope, then it only applies for the duration of that scope. Presumably, it would be easily visible to anyone looking at that scope.
>
> 2) I think we can all agree that if it is at module scope in the middle, that is probably bad coding style - especially if there are forward references to it.

Certainly.  However, it's been my experience that the vast majority of programmers on any given project tend not to be particularly scrupulous with their coding style, and code quality tends to degenerate over time.  Therefore, I believe that any means available to encourage good coding style and ease readability is worth considering quite carefully.  Having literally tossed old projects in the trash because the cost of maintenance was actually higher than a complete rewrite, I really can't stress this point enough.  But please note that I'm not suggesting a language or tool should in any way "dumb itself down" for the user, only that aesthetics plays a significant role in determining whether a particular feature or technique will be successful.

> 3) The with-import-as won't eliminate bad coding style with aliases. One can still plop an alias down in the middle of the module.

I do believe that bad code typically results from a few common causes:

* The programmer honestly doesn't know any better.  Often he's a novice or simply hasn't been exposed to the level of programming required for the task assigned.

* The programmer knows better but is in a hurry and doesn't care about cutting a few corners.  He'll go back and fix it when there's more time.  And that time will never be available.

In both of these cases, language aesthetics makes a difference.  In the first case, a mentor could suggest an alternate approach.  For this to succeed the learning programmer must be able to remember the solution and it must be fairly easy to execute.  If not, the programmer is destined to become a member of the second category, as he now knows better but finds some excuse not to use the technique anyway, often because he can't remember the details or because it requires too much typing.  In both cases, having support for the suggested technique built into the language or tool is ideal, as it presents both a syntactical reminder and a simpler way to accomplish the task than the programmer would be inclined to use otherwise.  Finally, if the technique *looks better* than another method and it's used pervasively, it will typically be followed by others (the broken window problem).

> 4) At least with aliases, they need to be defined within the module. This means one can do a simple search of one source file to find any aliases.

Given the size of some of the source files I've seen, even a directed keyword search may take some time.  This simply doesn't compare to a glance at the import line.

> Let's look a bit at the aesthetics:
> 
>     with foo.bar import
>         abc as def,
>         ghi as jkl,
>         mno;
> 
>     import very.long.name as N;
> vs:
>     static import foo.bar;
>         alias foo.bar.abc def;
>         alias foo.bar.ghi jkl;
>         alias foo.bar.mno mno;
> 
>     import very.long.name;
>         alias very.long.name N;
> 
> 
> Yes, the latter is more typing. If one was to do this a lot, it can get annoying. But is it going to be done a lot? I think that is the crux of the matter.

Assuming the language stays as-is, I believe the aliasing will likely be limited to instances where collisions occur, as the technique is easy to forget and requires a lot of typing.  I expect this will also lead to maintenance issues as library upgrades cause symbol collisions and such.

As for qualifiers themselves, I expect the typical module name to be at least two levels deep:

    import product.package.module;

and often more for large libraries.  Mango is a useful reference here, and serves to support this assertion.

> P.S. There are other possible syntaxes:
> 
>     import foo.bar
>     {    def = abc,
>         jkl = ghi,
>         mno,
>     }

As long as the syntax is aesthetically pleasing and logically/structurally similar to Kris' proposal, I won't bicker over minutiae.  That isn't too say I'm overly fond of the syntax you just suggested, but I do understand that a slightly different syntax may parse more easily or  better fit the 'feel' of the language as a whole.


Sean
July 11, 2006
>>
>> "Walter Bright" <newshound@digitalmars.com> wrote in message news:e8utvp$53$1@digitaldaemon.com...
>>> John Reimer wrote:
>>>> If you can find something
>>>> equivalent to from/as (which you most certainly haven't), without adopting new
>>>> syntax, maybe we'll bite... but so far, I think using 'with' (or from) and 'as'
>>>> is an excellent contender.
>>>
>>> I'll repeat myself here, too <g>. The 'static import' combined with 'alias' has
>>>
>>> *exactly the same semantics*
>>>
>>> as 'with' 'as'. The only difference between the proposals is if there are two statements or one. There is no difference in power or effect. There is nothing that one can do that the other cannot.
>>>
>>
>>
>> The semantics are not exactly the same.  Read Sean and Kris's explanations again, please.  'static import' adds nothing to the what this whole namespace business.  It just sharpens the compiler a bit to enforce FQN for the programmer's sake.  But that is absolutely unnecessary because a D programmer that wants to do that now can just make sure he uses FQNs!  So what's the point of 'static import'?
>
> I have to disagree with this. Currently, suppose you have a module that uses the toString() functions from std.string (and uses them hundreds of times). Then, you decide you need to use std.date in one place to get the current time. Suddenly, your module won't compile, because std.date.toString() conflicts with all the other toString()s that you're using. Even though you're not even using std.date.toString !
>

Fair enough.

I've seen this error also on several occasions.  I can't remember the exact source of it, but I think it's related to another issue.  It was my understanding that that was due to public imports somewhere up the line. This might have been one of the reasons why discussions started concerning a borked import system.  Perhaps I'm wrong?

There used to be confusion relating to D's name lookup mechanism. Importing a module into a class declaration was a huge mess, because people didn't realize how name lookup worked in D.


> With the static import proposal, you could just have
>
> import std.string;
> static import std.date;
>
> and then use FQNs for the single usage of date.
>


Er.. that tells me more that there's a problem with the original mechanism. And "static import" is a workaround.  Why not fix the original import system?  There must be something wrong with it.  So are we adding new constructs to workaround name clashes? Is that a good idea?  Is that the reason 'static import' was suggested?  There shouldn't be name clashes when fully qualified names are used in the first place! If there are, that's an unrelated problem and should be addressed and fixed, apart from this whole thread before we proceed.


> This is not a contrived example, I encountered it in my second D program (and I immediately thought that there were serious problems with the D module system. You're telling me I have to alias std.string.toString just because I want to use std.date.getUTCtime() ???). 'static import' would make it possible to avoid the use of FQNs in most cases; it would enable you to distinguish 'I'm going to use a function from this module' (static import) from 'I'm heavily depending on this module' (normal import).
>


I say 'static import' is a cheap fix for a major problem in the import system, then. :P


> Which is not to say that I'm favouring 'static import' in this discussion, I'm simply saying that all of the proposals, including static import, are an *enormous* improvement over what we have now.


I understand. But I still think that using 'static import' as a fix is not the solution.

-JJR
what we have now. 

July 11, 2006
In article <e8vlsn$19vu$1@digitaldaemon.com>, Walter Bright says...
>
>Bill Baxter wrote:
>> I think Python's import rules are generally quite sane, and D could do far worse than to copy Python's rules wholesale; however, note that Python 2.5 is getting a new feature related to importing relative to the current module: http://docs.python.org/dev/whatsnew/pep-328.html
>
>Thanks for the reference. Looks like they found that relative imports were a mistake, and want to move to absolute imports. D already uses an absolute import model, so there's no issue there for us.

I think D also has the edge on Python in terms of uniform syntax for importing modules as well as functions.  In Python to import a module it's:

import modulename.submodulename

but for functions or classes in a module you have to do

from modulename import functionname

D's way is better.  No matter what 'blah' is, if you want to import it, it's 'import blah.blah.blah;'.

Python's lack of a standard, simple way to provide module-level protection is annoying, too.  It makes it hard to tuck your implementation details out of the way.  For example, if module A uses some.really.massive.library in it's implementation and imports lots of symbols from it, and I "import A", then all the symbols A imported are visible as "A.___".  It makes it difficult to differentiate between A's implementation details and A's exports.  Users just see both thrown together in a big bag.

So really I should have said "You could do a lot worse than copying Python, but you can definitely do a lot better." :-)

>> Actually -- back to the avoiding new keywords discussion -- I'm curious why you can't just introduce 'as' or 'from' as new keywords that are ONLY keywords in an import statement.  Assuming you make the grammatical construct always begin with 'import' the production rules for the grammar should still be simple.
>
>The jargon for that is "context sensitive keywords". They prevent things like a clean lexical pass, mess up syntax highlighters, and generally cause trouble.

Been too long since I took a compiler course.  But I guess I can see how it's nice to be able to declare something unequivocally a keyword as early as possible in the lexing phase.  Thanks for the answer.

--Bill


July 11, 2006
Walter Bright wrote:
> kris wrote:
>> I suspect you are very confused about what is actually being asked for. Is that the case? Perhaps you'd like to note what it is that you think is being proposed?
> 
> 
> You prefer:
> 
>     with Foo import bar as abc;
> 
> instead of:
> 
>     static import Foo;
>     alias Foo.bar abc;
> 

As I suspected, you've been thoroughly confused by the sheer variety of options. What /I've/ been asking can be broken down into two parts:

part 1.

import lib.text.locale.convert as convert;

This imports all of the convert module symbols, and makes them available via a "locale." prefix. This is equivalent to your "static import" in conjunction with a relevant alias.

Replace the keyword "as" with ':' or '=' as desired.

-------------

Part 2.

This second aspect is entirely optional. It came about based on your initial suggestion, and imports distinct symbols instead of all:

import lib.text.locale.convert.Converter;

For those who want to rename it at the same time, append the "as" syntax. The rename might be used to resolve the conflicts within phobos, for example. Again this selective-import is secondary ~ that should have been made clear from the beginning. It would be wonderful to have this selective-import along with the former style, but given the current circumstances I'd say it can happily be dropped in favour of the former.

---------------


> 
>>>>  > 2) how much power it adds
>>>> It adds the ability to import specific symbols - a quite powerful addition to import I think.
>>>
>>> But that power already exists. 
>>
>> One can import only specific symbols at this time? Really?
> 
> 
> 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. (Python's documentation calls that "binding" a name into the local symbol table, but it's the same thing.)
> 
> With 'static import', the names aren't even put into the secondary namespace. Unaliased, they can only be accessed as FQN's. An alias can then be used to bind individual symbols into the current namespace.

I see; and this will encourage developers to use the safer approach?


> 
> (*) And yes, you can still access the other names in the static import via FQN's. A couple posters thought that might be a problem, but:
> 1) I doubt many are going to accidentally type in a FQN;
> 2) FQN's are not going to produce name collisions unless you happen to name your symbols the same as the topmost package name, which is just not realistically going to be a problem.
> 
> 
>>> The discussion is now about whether two statements should be combined into one or not. The power is the same.

Yes, it is. But not for the reasons you think. You clearly feel it's all about aesthetics, for something that will be used rarely.

I feel it's more to do with ease of use, ease of maintainablity, and ease of comprehension at a glance.

Furthermore, I feel it is not something that will be used rarely at all. Instead, the safe import should be used at /all/ times by those who wish to avoid the otherwise inevitable potential for namespace collisions.

This latter observation basically dictates that commercial software houses should not use the existing import, given its notable susceptibility to namespace collisions in anything other than small projects. Instead, they should use the /safe/ import at all times. However, you insist they should then either use FQS at all times, or alias every one of those safe imports.

Yes, I understand that you feel this aspect is utter nonsense. But then, compared to some people here, your experience in such things is not necessarily the most applicable ~ how can you possibly expect it to be?

The same thing happened with Associative Arrays: you didn't bother to solicit opinion on either of the two occasions when it was changed; and then subsequently complained when people still found issue with you alternate changes. It's still not right to this day. I see the same pattern here. And for what?

Anyone would think we were trying to sabotage the language, when instead we're trying to get it into the shape needed for us to introduce it within the corporate realm.



July 11, 2006
"kris" <foo@bar.com> wrote in message news:e8votm$1e76$1@digitaldaemon.com...
> Walter Bright wrote:
>> kris wrote:
>>> I suspect you are very confused about what is actually being asked for. Is that the case? Perhaps you'd like to note what it is that you think is being proposed?
>>
>>
>> You prefer:
>>
>>     with Foo import bar as abc;
>>
>> instead of:
>>
>>     static import Foo;
>>     alias Foo.bar abc;
>>
>
> As I suspected, you've been thoroughly confused by the sheer variety of options. What /I've/ been asking can be broken down into two parts:
>
> part 1.
>
> import lib.text.locale.convert as convert;
>
> This imports all of the convert module symbols, and makes them available via a "locale." prefix. This is equivalent to your "static import" in conjunction with a relevant alias.

I want to note a correction here.  Kris means "This imports all of the convert module symbols, and makes them available via 'convert.' prefix."

A little mistake... but just so people don't get confused. :)

-JJR 

July 11, 2006
Actually, I just want to make a correction.  The problem you describe, Don, is very much related to this whole issue (after I did some reading up on the name collision thing to understand it more), but I still don't consider the "static import" a proper fix.

-JJR


"Don Clugston" <dac@nospam.com.au> wrote in message news:e8vn6d$1bm0$1@digitaldaemon.com...
> John Reimer wrote:
>>
>> "Walter Bright" <newshound@digitalmars.com> wrote in message news:e8utvp$53$1@digitaldaemon.com...
>>> John Reimer wrote:
>>>> If you can find something
>>>> equivalent to from/as (which you most certainly haven't), without adopting new
>>>> syntax, maybe we'll bite... but so far, I think using 'with' (or from) and 'as'
>>>> is an excellent contender.
>>>
>>> I'll repeat myself here, too <g>. The 'static import' combined with 'alias' has
>>>
>>> *exactly the same semantics*
>>>
>>> as 'with' 'as'. The only difference between the proposals is if there are two statements or one. There is no difference in power or effect. There is nothing that one can do that the other cannot.
>>>
>>
>>
>> The semantics are not exactly the same.  Read Sean and Kris's explanations again, please.  'static import' adds nothing to the what this whole namespace business.  It just sharpens the compiler a bit to enforce FQN for the programmer's sake.  But that is absolutely unnecessary because a D programmer that wants to do that now can just make sure he uses FQNs!  So what's the point of 'static import'?
>
> I have to disagree with this. Currently, suppose you have a module that uses the toString() functions from std.string (and uses them hundreds of times). Then, you decide you need to use std.date in one place to get the current time. Suddenly, your module won't compile, because std.date.toString() conflicts with all the other toString()s that you're using. Even though you're not even using std.date.toString !
>
> With the static import proposal, you could just have
>
> import std.string;
> static import std.date;
>
> and then use FQNs for the single usage of date.
>
> This is not a contrived example, I encountered it in my second D program (and I immediately thought that there were serious problems with the D module system. You're telling me I have to alias std.string.toString just because I want to use std.date.getUTCtime() ???). 'static import' would make it possible to avoid the use of FQNs in most cases; it would enable you to distinguish 'I'm going to use a function from this module' (static import) from 'I'm heavily depending on this module' (normal import).
>
> Which is not to say that I'm favouring 'static import' in this discussion, I'm simply saying that all of the proposals, including static import, are an *enormous* improvement over what we have now. 

July 11, 2006
Walter Bright wrote:

> John Reimer wrote:
>> The use of "alias" still looks like a hack.  We know you've always been
>> firm in
>> your belief that "alias" is the way to do it.  I doubt that all these
>> people would be discussing options here if they were satisfied with that
>> solution (which has been around for a looong time).
>> 
>> We know it can be done with alias. Kris knows. We don't think it's good enough. That's why this whole topic is being wrangled.
>> 
>> So if you choose to make the internal machinery do it with alias, fine! We just want something that's better, nicer, more professional looking! :) (please not "static import," though).
> 
> What I don't get is what is "unprofessional" or hackish about alias? Is it (as I posted to Kris) that it looks too much like #define?

I personally don't like it myself, first of all it is not a natural word for me (I don't have English as my mother tongue, might very well be the reason), but my understanding of the word make it very unlikely to me that it actually _do_ something, it should just give something a different name. Using it for anything else (pulling something from one namespace to another, for instance when subclassing), or for making namespaces, is to me the most unintuitive thing I've ever come across in a programming language (I don't count COBOL here ...). I actually hate it :)

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource & #D: larsivi
July 11, 2006
Derek Parnell wrote:

> On Sat, 08 Jul 2006 18:07:34 +1000, Ivan Senji <ivan.senji_REMOVE_@_THIS__gmail.com> wrote:
> 
>> Derek Parnell wrote:
>>> On Sat, 08 Jul 2006 14:47:34 +1000, Walter Bright <newshound@digitalmars.com> wrote:
>>>
>>>> Brad Roberts wrote:
>>>
>>>>>  How much begging would it take to try for a release or two having
>>>>> private symbols invisible to the importer?  It's really much more
>>>>> intuitive, imho.  I haven't looked at this part of the front end
>>>>> code, but if it's easy, feel free to make it controllable via a
>>>>> compiler option just for the experiment's time frame.
>>>>
>>>> The problems happen when one has:
>>>>
>>>> void foo(int x);
>>>> private void foo(long x);
>>>>
>>>> So the first foo is found, then overload rules apply, and the second foo is selected.
>>>
>>> No.... what would happen if something outside the module called
>>> foo(long) is that foo(int) would be called due to implicit casts and
>>> that the module's foo(long) is invisible to the caller. It wouldn't be
>>> called because the caller should not be able to see it.
>>>
>>
>> Yes, but:
>> If the functions were actually:
>>
>> void foo(int x);
>> private void foo(char[] x);
>>
>> and in another module foo("bar"); the right function would be called
>> even though it is private.
>> The problem: the caller does see it if there is another function with
>> the same name.
> 
> I agree that that is the problem. Calling foo("bar") should fail as that is private to the module and the caller should not be able to access it *BECAUSE* it is private even though the compiler can actually 'see' it.
> 

I agree, private means private.

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource & #D: larsivi
July 11, 2006
Walter Bright wrote:
> But is it going to be done a lot? 

assuming we get static import i think this will get done a lot
static import foo.bar.m;
alias foo.bar.m m;

which I would prefere to write as
import foo.bar.m as m;

I think the among the C++ crowd the people who refuse to use using namespace would use the more qualified form and thous who use using wont. As I think D will attract many C++ programmers and for and against using is an argument i here a lot (many on the different sides where i come from) i think the D language will appeal more to C++ programmers if as is introduced as it look cleaner and the more programmer a language can appeal to the more it will bee used.