July 11, 2006
"Rioshin an'Harthen" <rharth75@hotmail.com> wrote:

Here I am, replying to my own post... :)

> I would prefer the syntax to be something akin to
>
> alias import module.with.a.long.name MWLN;
>
> which would be exactly like
>
> static import module.with.a.long.name;
> alias module.with.a.long.name MWLN;

I thought about it a little more, and came up with the following:

import module.name; - current import
static import module.name; - require FQN import
import module.name alias MN; - current import with automatic alias
static import module.name alias MN; - require FQN import with automatic
alias

Basically thus:

The import statement imports the module, and enables the use of functions, classes, etc. of the module using just the name of the function, class, etc., or through a fully qualified name.

    import module.name; // contains function foo
    foo();    // legal
    module.name.foo();    // legal
    MN.foo();    // illegal

The static import statement is like the import statement, but requires the use of the fully qualified name to access functions, classes, etc.

    static import module.name;
    foo();    // illegal
    module.name.foo();    // legal
    MN.foo();    // illegal

The import ... alias statement is like the import statement, but adds the alias as an optional method of calling the functions, classes, etc.

    import module.name alias MN;
    foo();    // legal
    module.name.foo();    // legal
    MN.foo();    // legal

The static import ... alias statement is like the static import statement, but adds the alias as an optional method of calling the functions, classes, etc.

    static import module.name alias MN;
    foo();    // illegal
    module.name.foo();    // legal
    MN.foo();    // legal


July 11, 2006
On Tue, 11 Jul 2006 21:12:59 +1000, Rioshin an'Harthen <rharth75@hotmail.com> wrote:


>
> I thought about it a little more, and came up with the following:
>
> import module.name; - current import
> static import module.name; - require FQN import
> import module.name alias MN; - current import with automatic alias
> static import module.name alias MN; - require FQN import with automatic
> alias

Snap! This was also my suggestion ;-) Additionally, I extended this idea to also allow for selective imports of individual members from the module rather than all the members.

 static import in module.name alias MN member1 alias m1, member2, member3, ... ;

 MN.memb3()
 MN.m1()

-- 
Derek Parnell
Melbourne, Australia
July 11, 2006
Bill Baxter wrote:

> static import module.with.a.long.name.string;
> alias module.with.a.long.name.string Str;

import module.with.a.long.name.string as Str;

This keeps "Str" and the module name and the word import on one line, making it hugely easier to grep for them.
July 11, 2006
On Tue, 11 Jul 2006 15:56:44 +0300, Georg Wrede <georg.wrede@nospam.org> wrote:
> Bill Baxter wrote:
>
>> static import module.with.a.long.name.string;
>> alias module.with.a.long.name.string Str;
>
> import module.with.a.long.name.string as Str;
>
> This keeps "Str" and the module name and the word import on one line, making it hugely easier to grep for them.

Assuming the coder wasn't a 'half sane monkey on crack' you should be able to open the file in an editor, go to the top and do a search/find on "Str", the first result should find it. Anything else is either bad programming practice or a moderately rare case where 2 things include each other and so one uses the other before it's declaration.

Regan
July 11, 2006
On Wed, 12 Jul 2006 01:03:16 +1200, Regan Heath <regan@netwin.co.nz> wrote:
> On Tue, 11 Jul 2006 15:56:44 +0300, Georg Wrede <georg.wrede@nospam.org> wrote:
>> Bill Baxter wrote:
>>
>>> static import module.with.a.long.name.string;
>>> alias module.with.a.long.name.string Str;
>>
>> import module.with.a.long.name.string as Str;
>>
>> This keeps "Str" and the module name and the word import on one line, making it hugely easier to grep for them.
>
> Assuming the coder wasn't a 'half sane monkey on crack' you should be able to open the file in an editor, go to the top and do a search/find on "Str", the first result should find it. Anything else is either bad programming practice or a moderately rare case where 2 things include each other and so one uses the other before it's declaration.

In fact a good UI should be able to take you to the declaration of a symbol with the press of a single button, like F12 in developer studio does when you have browse info enabled.

Regan
July 11, 2006
"Derek Parnell" <derek@psych.ward> wrote:
> On Tue, 11 Jul 2006 21:12:59 +1000, Rioshin an'Harthen wrote:
>> I thought about it a little more, and came up with the following:
>>
>> import module.name; - current import
>> static import module.name; - require FQN import
>> import module.name alias MN; - current import with automatic alias
>> static import module.name alias MN; - require FQN import with automatic
>> alias
>
> Snap! This was also my suggestion ;-) Additionally, I extended this idea to also allow for selective imports of individual members from the module rather than all the members.
>
>  static import in module.name alias MN member1 alias m1, member2, member3,
> ... ;
>
>  MN.memb3()
>  MN.m1()

Great minds, eh? :)

I'm giving this a definite thumbs up. Sometimes, it's quite good to only import selected members (which I didn't take into account in my post - I would probably have come up with something akin to what you show).


July 11, 2006
"Bill Baxter" <Bill_member@pathlink.com> wrote in message news:e8v32s$65i$1@digitaldaemon.com...
> In article <e8urqt$2vb2$1@digitaldaemon.com>, Ameer Armaly says...
>>...
>>It might just be me, but IMHO you're trying to mix apples with oranges;
>>either you want fully qualified imports or you want standard imports.  If
>>you desperately want to mix them, then I agree with Walter in that aliases
>>should be just fine; anyone with half a brain will put them right near the
>>import where they can be seen; anyone who doesn't do that is just a bad
>>coder.
>
> Good points.
>
> But
> A) renaming modules is pretty common once you allow FQN import.
>
Why?  Isn't the point of fqn importing to prefix the module name?  This goes back to the idea that either you import the module in to the global namespace or you deal with the full name; I just don't see this being done very often, especially with well known libraries.
> static import module.with.a.long.name.string;
> alias module.with.a.long.name.string Str;
>
> It would be nice to be able to put those into one statement so that the
> module
> name doesn't have to be typed in twice.
>
> B) Sometimes you want to keep your namespace clean except for a handful of specific symbols from some module:
>
> static import module.with.a.long.name;
> alias module.with.a.long.name.foo Foo;
> alias module.with.a.long.name.bar Bar;
> alias module.with.a.long.name.baz Baz;
>
> That would also be easier to read,write, and maintain if
> module.with.a.long.name
> didn't appear 4 times.
>
> Granted, you could do:
> static import module.with.a.long.name;
> alias module.with.a.long.name MWLN;
> alias MWLN.foo Foo;
> alias MWLN.bar Bar;
> alias MWLN.baz Baz;
>
> which is better, but the full module name still appears twice, and I
> didn't
> really want MWLN or module.with.a.long.name in my namespace to begin with.
>
Why not then just import the whole module in to the namespace?  It's not as if the namespace is something you actually look and see "god this is cluttered with junk," so I really don't see the point.  If a module is written in such a way as to force you to go to these lengths to optimally use it then it's badly written.
> However, I'm starting to agree with Walter, on that one.  There probably
> aren't
> too many times when you want to import specific symbols without also
> wanting
> access to the module as a whole.  In the example I gave from my python
> code,
> "from numpy import transpose as T", the truth is that I also do "import
> numpy as
> num" in that code.  So I could have just said "T = num.transpose", which
> would
> be the equivalent of D's "alias num.transpose T;".
>
> That still leaves the need for some sort of way to do:
> static import module.with.a.long.name as MWLN;
> in which MWLN is the *only* symbol introduced into the current namespace.
> (Although I guess in the import-and-rename case 'static' would be
> redundant, or
> just incorrect since the name *is* changing.)
>
>
> 


July 11, 2006
Ameer Armaly wrote:
> "Bill Baxter" <Bill_member@pathlink.com> wrote in message news:e8v32s$65i$1@digitaldaemon.com...
>> In article <e8urqt$2vb2$1@digitaldaemon.com>, Ameer Armaly says...
>>> ...
>>> It might just be me, but IMHO you're trying to mix apples with oranges;
>>> either you want fully qualified imports or you want standard imports.  If
>>> you desperately want to mix them, then I agree with Walter in that aliases
>>> should be just fine; anyone with half a brain will put them right near the
>>> import where they can be seen; anyone who doesn't do that is just a bad
>>> coder.
>> Good points.
>>
>> But
>> A) renaming modules is pretty common once you allow FQN import.
>>
> Why?  Isn't the point of fqn importing to prefix the module name?  This goes back to the idea that either you import the module in to the global namespace or you deal with the full name; I just don't see this being done very often, especially with well known libraries.
>> static import module.with.a.long.name.string;
>> alias module.with.a.long.name.string Str;
>>
>> It would be nice to be able to put those into one statement so that the module
>> name doesn't have to be typed in twice.
>>
>> B) Sometimes you want to keep your namespace clean except for a handful of
>> specific symbols from some module:
>>
>> static import module.with.a.long.name;
>> alias module.with.a.long.name.foo Foo;
>> alias module.with.a.long.name.bar Bar;
>> alias module.with.a.long.name.baz Baz;
>>
>> That would also be easier to read,write, and maintain if module.with.a.long.name
>> didn't appear 4 times.
>>
>> Granted, you could do:
>> static import module.with.a.long.name;
>> alias module.with.a.long.name MWLN;
>> alias MWLN.foo Foo;
>> alias MWLN.bar Bar;
>> alias MWLN.baz Baz;
>>
>> which is better, but the full module name still appears twice, and I didn't
>> really want MWLN or module.with.a.long.name in my namespace to begin with.
>>
> Why not then just import the whole module in to the namespace?  It's not as if the namespace is something you actually look and see "god this is cluttered with junk," so I really don't see the point.  If a module is written in such a way as to force you to go to these lengths to optimally use it then it's badly written.

Because the problems only really happen when you import more than one module. The existing system copes well with a single import. If something in the import has the same name as the function in your primary file, they don't conflict, because the primary namespace is searched before the imported one. But, if you import from two files, you can have a naming conflict in the secondary namespace. You have no choice -- you *have* to use FQN.


Currently, I would maintain that it is not possible to use unqualified names safely in any file which imports more than one module. 'static import' would make it always safe to use one non-qualified module, and an arbitrary number of FQN modules. In any other configuration, adding a new function to a module can break existing code which imports it.
July 11, 2006
Walter Bright escribió:
> John Reimer wrote:
>> And Walter, you particularly seem to be stirring this pot by repeatedly posting
>> misinformation.  We have several times demonstrated the difference between the
>> two systems.  If you don't understand what we are saying is different, please
>> ask us to clarify rather than adamantly stating in every post that there is
>> *nothing* different between the two.  The difference has been clearly
>> demonstrated more than once.  You seem to be refusing to admit it.
> 
> So I've apparently missed something. Please explain what the semantic difference is.

Here's what I've understood:

(Using Rioshin's examples)

You propose this:

    static import module.name;
    alias module.name.foo bar;

    foo();    // illegal
    module.name.foo();    // legal
    bar();    // legal

With minor syntax variations, here's what others are proposing:

    with module.name import foo as bar;

    foo();    // illegal
    module.name.foo();    // illegal
    bar();    // legal

Notice how the FQN would be illegal.

(That's basically it, right?)

====

Personally, I think both "static import" (or some variation of it), selective import (with .. import ..) and import with aliasing (import .. as ..) are needed. However, I don't like the "as" syntax: I think a symbol would make it easier to read. My preferred choice would be =, but like this:

    with a.b.c import f1 = foo1, f2 = foo2, f3 = foo3;

(Where f1, f2 and f3 are the aliased names.) I think the symbols provide visual stops to understand clearly what's going on. That also makes me dislike:

    import a.b.c d;

Because the space is easy to miss. IMO

-- 
Carlos Santander Bernal
July 11, 2006
"Rioshin an'Harthen" <rharth75@hotmail.com> wrote:
> "Derek Parnell" <derek@psych.ward> wrote:
>> On Tue, 11 Jul 2006 21:12:59 +1000, Rioshin an'Harthen wrote:
>>> import module.name; - current import
>>> static import module.name; - require FQN import
>>> import module.name alias MN; - current import with automatic alias
>>> static import module.name alias MN; - require FQN import with automatic
>>> alias
>>
>> Snap! This was also my suggestion ;-) Additionally, I extended this idea to also allow for selective imports of individual members from the module rather than all the members.
>>
>>  static import in module.name alias MN member1 alias m1, member2,
>> member3, ... ;
>>
>>  MN.memb3()
>>  MN.m1()
>
> Great minds, eh? :)
>
> I'm giving this a definite thumbs up. Sometimes, it's quite good to only import selected members (which I didn't take into account in my post - I would probably have come up with something akin to what you show).

A little further thought into this:

[<protection>] [static] import {[in]} <FQN Module> [alias <Module Alias>] {[<<Member> [alias <Member Alias>]>[, ...]]};

where [] denotes optionality, {} requiring all if one, and <> a symbol name.

This would allow for example the following syntaxes:

private import module.name;
import module.name alias mn;
import in module.name member1, member2;
import in module.name alias mn member1, member2 alias m2;
private static import in module.name alias mn member1 alias m1, member2
alias m2, member3 alias m3;

(where I would probably write the last one as something like

    private static import
        in module.name alias mn
            member1 alias m1,
            member2 alias m2,
            member3 alias m3;

, but I digress).

It could even be considered that any occurence of alias be replaced with alias|as, where | denotes that either but not both be used, and the difference being alias allowing the use of both forms (FQN or aliased name), while as requiring the use of the aliased name. However, this would be a complexity I would not want to write into the compiler. :) But it would fill in the forms from my previous post:

    import module.name;
    foo();    // legal
    module.name.foo();    // legal
    mn.foo();    // illegal, no alias or as

    import module.name alias mn;
    foo();    // legal
    module.name.foo();    // legal
    mn.foo();    // legal

    import module.name as mn;
    foo();    // legal since not static import
    module.name.foo();    // illegal since "as" is used
    mn.foo();    // legal

    static import module.name;
    foo();    // illegal, static import
    module.name.foo();    // legal
    mn.foo();    // illegal, no alias or as

    static import module.name alias mn;
    foo();    // illegal, static import
    module.name.foo();    // legal
    mn.foo();    // legal

    static import module.name as mn;
    foo();    // illegal, static import
    module.name.foo();    // illegal since "as" is used
    mn.foo();    // legal

Not that I'm proposing this distinction - I believe it is an unnecessary complication. I think "alias" is enough - we can use the fully qualified name if necessary (sometimes, it's good for code clarity to use in a function or method the fully qualified name, and then using the short form created with an alias), while using the aliased form most of the time.

The import syntax could be something akin to (with the optional as in brackets):

ImportDeclaration:
    ProtectionAttribute 'static' ImportStatement ;
    ProtectionAttribute ImportStatement ;
    'static' ImportStatement ;
    ImportStatement ;

ProtectionAttribute:
    'private'
    'public'
    (and whatever others deemed necessary)

ImportStatement:
    'import' 'in' ModuleDeclaration MemberDeclarationList
    'import' ModuleDeclarationList

ModuleDeclarationList:
    ModuleDeclaration
    ModuleDeclaration , ModuleDeclarationList

ModuleDeclaration:
    ModuleName 'alias' AliasedModuleName
    [ModuleName 'as' AsModuleName]
    ModuleName

MemberDeclarationList:
    MemberDeclaration
    MemberDeclaration , MemberDeclarationList

MemberDeclaration:
    MemberName 'alias' AliasedMemberName
    [MemberName 'as' AsMemberName]
    MemberName

This grammar would allow for multiple modules to be imported on one line, provided we don't try to import specific members from it, while allowing for specific members to be imported (requiring one import statement per module when only picking certain members from it).