Import concerns revisited

Sean Kelly sean at f4.ca
Sun Jul 9 12:07:44 PDT 2006


Walter Bright wrote:
> kris wrote:
>> The use of alias, regarding imports, should very likely be kept to a 
>> bare minimum in anything other than Q&D development. Ideally zero.
> 
> I really don't understand your pov. I can't help but think you regard 
> alias as like C++'s #define:
> 
>     alias foo bar;
>     #define bar foo
> 
> Such #define's I would agree are a terrible hack that don't belong in 
> professional code. But aliasing isn't like that, it's a sane and 
> well-behaved replacement.

I think Kris was merely suggesting that the need for a separate alias 
declaration for each import was the problem, not the idea of aliasing 
itself.  If a particular module imports 10 others, that's 10 separate 
aliases required as well, and there's no good way to write them in a way 
that makes for easy readability and maintenance.  This is the point he 
was trying to make below.

>> It's like the use of goto ~ use it where it can really help, but 
>> otherwise consider alternatives instead. I don't know what kind of 
>> development-scales you have in mind for D, but I'll happily testify 
>> that a boatload of aliases littering the imports would have no place 
>> in any project I'm responsible for; nor in those of the people I 
>> learned from. Here's why:
>>
>> Quantities of alias do little but complicate ones comprehension of the 
>> code. Having a second-step (import then alias) is not only messy for 
>> each import, it does nothing to /encourage/ smart usage of namespace 
>> seperation. In fact, the extra step will likely discourage everyone 
>> but the diehards from using anything but the current global namespace, 
>> and we'll end up right back at square one.
> 
> With the "static import", there is no longer any possibility of name 
> collisions, so we're not at square one. With no aliases, fully qualified 
> module contents lookup will be needed.

As above, the issue here was the need for a separate alias line to 
accomplish what was suggested by the "as" syntax, not the aliasing 
concept itself.

>> At that point, the language would be lacking. And why? This is all 
>> about maturity and usability of the language in specific areas. Why 
>> the rollback to something that can be considered "arcane" instead?
> 
> I don't see it as arcane or a workaround. Symbolic aliasing is a very 
> powerful feature - yet it's very simple.

And I think we all agree here.

>> Hey ~ if you'd actually roll in the changes, I'd be happy to make them 
>> myself ... I'd add both selective import and the "as" variation ~ a 
>> flexible combination to handle all cases, including the one Derek 
>> astutely pointed out. No aliases required by the user:
>>
>> // import as we know it today, and with a required prefix "locale."
>> import lib.text.locale;
>> import lib.text.locale as locale;
>>
>> // selective import of one entity, and alternatively with an alias
>> import lib.text.locale.Time;
>> import lib.text.locale.Time as otherTime;
>>
>> ==================================
> 
> But those *are* aliases. It's just using a different keyword, "as" 
> instead of "alias", and a slightly rearranged syntax. So what's the 
> difference between:
> 
> import lib.text.locale.Time as otherTime;
> 
> and:
> 
> alias lib.text.locale.Time otherTime;
> 
> ? Absolutely none, unless I am totally misunderstanding your proposal.

The alias version actually requires two lines, given current compiler 
behavior:

import lib.text.locale;
alias  lib.text.locale locale;

(I'm focusing on the module "as" syntax here since it's what was 
discussed above)

I think Kris is saying that although the "as" syntax just syntactic 
sugar for the above, it's also more readable and more maintainable.  And 
its presence as a language feature would encourage use of what is a good 
programming practice--anything too unwieldy will only be common among 
the truly fastidious.

>> Okay. Let's reflect for a moment?
>>
>> The functionality is there, but the syntax could probably be better? 
>> There's a number of other posts proposing the use of "with" and so on, 
>> which look rather promising (from Kirk & Derek):
>>
>> with lib.text.locale import Time, Date;
>>
>> Seems pretty darned clear what's going on there. Seems to me that's a 
>> much more user-focused solution for selective imports. Let's combine 
>> this with a means to import an entire module under a prefix, as we've 
>> previously seen:
>>
>>      // import as we know it today
>> import lib.text.locale;
>> auto time = new Time;
>>
>>      // "locale." prefix required (great for IFTI modules)
>> import lib.text.locale as locale;
>> auto utc = locale.utcTime();
>> auto dst = locale.daylightSavings();
>>
>>      // selective import
>> with lib.text.locale import Time, Date;
>> auto time = new Time;
>> auto date = new Date;
>>
>>      // selective import with alias
>> with lib.text.locale import Time, Date as MyDate;
>> auto time = new Time;
>> auto date = new MyDate;
>>
>> ==================================
>>
>> How about it?
> 
>       // "locale." prefix required (great for IFTI modules)
> static import lib.text.locale;
> alias lib.text.locale locale;
> auto utc = locale.utcTime();
> auto dst = locale.daylightSavings();

Assuming just the static import line, symbols must be fully qualified, 
yes?  So to allow just a "locale." prefix the additional alias line is 
still required?  This doesn't seem to address Kris' concerns regarding 
maintenance and readability.

>      // selective import
> static import lib.text.locale;
> alias lib.text.locale.Time Time;
> alias lib.text.locale.Date Date;
> auto time = new Time;
> auto date = new Date;
> 
>      // selective import with alias
> static import lib.text.locale;
> alias lib.text.locale.Time Time;
> alias lib.text.locale.Date MyDate;
> auto time = new Time;
> auto date = new MyDate;
> 
> These are semantically identical. The "static import" is a bit ugly 
> looking, ok. It's a little wordier, ok. But it does work and produces 
> exactly the results you asked for.

A normal import followed by an alias works nearly as well as the above, 
too, but neither is nearly as elegant as the "as" syntax, which I 
believe is a significant issue here.  If you don't mind my asking, 
what's wrong with Kris' proposal?  Are there parsing issues, do you feel 
there's a problem with its impact on code readability, etc?

> Let's harken back to the special regexp syntax I tried out a few months 
> ago. It was a bit of syntactic sugar that reduced typing significantly. 
> But it was soundly rejected by the community as adding complexity (in 
> the form of more language to learn) while actually adding little to no 
> extra power.

Regarding the Regexp syntax, my only personal objection was to the 
bindings the default implementation created between runtime and standard 
library code (and I remember this being an issue for Kris as well). 
Another issue I remember was that the current Regexp implementation 
lacks robust Unicode support, and tying a specific (arguably lacking) 
implementation into the language didn't appeal to some.  But I don't 
remember anyone complaining about the need to learn more language 
syntax.  Perhaps that was after I stopped paying close attention to the 
discussion as things degenerated?

> The "with" and "as" syntaxes add no power - they just save a little 
> typing at the expense of adding more complexity to the grammar. Is that 
> a worthwhile tradeoff? I don't know, but my inclination is to be 
> conservative about such things.

I think this may be the crux of the issue.  Kris is approaching things 
from a user's standpoint while you're approaching things from an 
implementer's standpoint.  I believe Kris feels strongly about this 
because it appears to provide a good bit of additional clarity and 
utility (in the form of reduced maintenance and encouraging good 
programming practice) for an apparently small amount of additional 
complexity on the compiler side.  You, however, see little point in 
adding this complexity if it doesn't provide anything that is not 
technically possible now.  Is this correct?

You said to John R. that you do listen to convincing arguments and I 
know this is true from experience, but we're at the point with 1.0 
features where the outstanding issues concern utility and 
aesthetics--areas where it's nearly impossible to make an argument on 
purely logical grounds.  I think one aspect of D that most of us find 
incredibly appealing is its sense of aesthetics--the language tends to 
naturally encourage the production of elegant code--and it's clear you 
agree that this results in code that has fewer bugs and is more easily 
maintainable than its C++/Java/whatever counterpart.

Kris' argument, to me, seems built on this ideal by attempting to 
provide simple extensions that would further enhance what many of us see 
as the primary strength of this language.  Therefore, I don't understand 
the resistance to his suggestions, and I'm at a loss for how to back up 
an argument that can only be made on aesthetic, predictive, and 
hypothetical grounds.  I believe, as Kris does, that his suggestions 
would reduce maintenance cost and to do so in a way that seems 
consistent with the design goals of this language.  But until D gets to 
the point where it is actually used for large projects over a period of 
years, it will be difficult to point at a use case and say "if we'd have 
had this feature these problems would not have occurred."  Here, I can 
only defer to Kris' experience, supported by my own, and say that I 
believe his suggestions are good ones and that they would more than 
justify their presence when D reaches this level of maturity.

> I suggest trying out the "static import" for a while. See how it works 
> and looks.

I can tell you right now that I don't like the way "static import" 
looks, and I'm not terribly happy that I would need to continue 
maintaining a separate "alias" line for each import.  And that won't 
change with experience.  Might I ask why "static import" was chosen as 
the syntax for this feature?  Prepending "static" to "import" doesn't 
convey any meaning to me as a user about what's actually happening, so I 
can only conclude that this syntax was chosen because it's easy to 
implement and doesn't add any new keywords to the language?  I don't 
suppose any subset of Kris' suggestions could be implemented for 
comparison?  Or perhaps GDC would make a more appropriate testing ground 
for user-driven feature requests?  You've suggested we try out "static 
import" for a while, but that hardly puts Kris' proposal on equal 
footing for comparison.  And I personally don't want to feel I'm 
settling for "static import" simply because it was the only option we 
were offered.


Sean



More information about the Digitalmars-d mailing list