www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12359] New: implicit overload merging with selective/renamed imports should be removed

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359

           Summary: implicit overload merging with selective/renamed
                    imports should be removed
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: k.hara.pg gmail.com


--- Comment #0 from Kenji Hara <k.hara.pg gmail.com> 2014-03-13 17:22:11 PDT ---
Currently, selective or renamed imports create alias declaration implicitly.

  import a : b;
  // is mostly equivalent with:
  // import a; alias b = a.b;

  import a : x = b;
  // is mostly equivalent with:
  // import a; alias x = a.b;

But it is problematic behavior, because it would implicitly merge overloads in
the imported module. For example:

  import std.ascii : isDigit;   // bool isDigit(dchar c)

  bool isDigit(char c) { return true; }
  // Here isDigit is an overload set of bool(char) and bool(dchar)

  void main() {
    dchar d = 'a';
    isDigit(d);   // matches to std.ascii.isDiigt
  }

I think import declarations should only handle symbol visibility. So the
current behavior is not orthogonal. Therefore it should be deprecated and
finally removed.

To reproduce same behavior, explicit alias should work.

  import std.ascii : isDigit;   // Don't create alias silently

  bool isDigit(char c) { return true; }
  alias isDigit = std.ascii.isDigit;  // explicitly merge overloads

  void main() {
    dchar d = 'a';
    isDigit(d);   // matches to std.ascii.isDiigt
  }

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 13 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull


--- Comment #1 from Kenji Hara <k.hara.pg gmail.com> 2014-03-13 17:59:49 PDT ---
The compiler change to show deprecation messages:

https://github.com/D-Programming-Language/dmd/pull/2256

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 13 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com


--- Comment #2 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2014-03-14
00:22:31 PDT ---
(In reply to comment #0)
 To reproduce same behavior, explicit alias should work.
 
   import std.ascii : isDigit;   // Don't create alias silently
 
   bool isDigit(char c) { return true; }
   alias isDigit = std.ascii.isDigit;  // explicitly merge overloads

I don't see how this can work, "std.ascii" should not be visible in the last statement. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359



--- Comment #3 from Kenji Hara <k.hara.pg gmail.com> 2014-03-14 06:55:24 PDT ---
(In reply to comment #2)
 (In reply to comment #0)
 To reproduce same behavior, explicit alias should work.
 
   import std.ascii : isDigit;   // Don't create alias silently
 
   bool isDigit(char c) { return true; }
   alias isDigit = std.ascii.isDigit;  // explicitly merge overloads

I don't see how this can work, "std.ascii" should not be visible in the last statement.

I think selective imports should make the fully qualified module name still visible. It's consistent behavior with basic imports. ==== For the future enhancement, I'm planning to add variations of import declarations. Just the ideas: 1. static selective import static import std.stdio : writeln; //writeln(); // NG std.stdio.writeln(); // OK //std.stdio.writefln(""); // NG 2. static renamed import static import io = std.stdio; //writeln(); // NG //std.stdio.writeln(); // NG io.writeln(); // OK 3. static selective renamed import static import io = std.stdio : writeln; io.writeln(); // OK //io.writefln(""); // NG 4. unnamed import import = std.stdio; writeln(); // OK writefln(""); // OK //std.stdio.writeln(); // NG 5. unnamed selective import import = std.stdio : writeln; writeln(); // OK //writefln(""); // NG //std.stdio.writeln(); // NG They are much flexible than the current behavior. Increasing orthogonality will give to programmers the ability to control imported names more precisely. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359



--- Comment #4 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2014-03-14
07:14:39 PDT ---
(In reply to comment #3)
 I think selective imports should make the fully qualified module name still
 visible. It's consistent behavior with basic imports.

Ok.
 4. unnamed import
 
   import = std.stdio;
   writeln();  // OK
   writefln("");  // OK
   //std.stdio.writeln();  // NG

My initial reaction is that I'm not a fan of this syntax. But anyway, we can discuss this later. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #5 from bearophile_hugs eml.cc 2014-03-14 07:18:01 PDT ---
(In reply to comment #3)

 4. unnamed import
 
   import = std.stdio;
   writeln();  // OK
   writefln("");  // OK
   //std.stdio.writeln();  // NG
 
 5. unnamed selective import
 
   import = std.stdio : writeln;
   writeln();  // OK
   //writefln("");  // NG
   //std.stdio.writeln();  // NG

This will need to be discussed. I don't like this a lot. What's the purpose of this? -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359



--- Comment #6 from Kenji Hara <k.hara.pg gmail.com> 2014-03-14 07:36:42 PDT ---
(In reply to comment #5)
 (In reply to comment #3)
 
 4. unnamed import
 
   import = std.stdio;
   writeln();  // OK
   writefln("");  // OK
   //std.stdio.writeln();  // NG
 
 5. unnamed selective import
 
   import = std.stdio : writeln;
   writeln();  // OK
   //writefln("");  // NG
   //std.stdio.writeln();  // NG

This will need to be discussed. I don't like this a lot. What's the purpose of this?

They are just funny ideas to mask fully qualified names. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 14 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359



--- Comment #7 from github-bugzilla puremagic.com 2014-03-15 16:49:21 PDT ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/614158f3e8ca5af8a512120baa24e655bdb57890
Add test case for issue 12359 before deprecation

https://github.com/D-Programming-Language/dmd/commit/45d55309d594446cb509ae1b8d4ba1fa69205bfa
fix Issue 12359 - implicit overload merging with selective/renamed imports
should be removed

Show deprecation message for the implicitly merged overload set, by using
cross-module overload set mechanism.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 15 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359



--- Comment #8 from Kenji Hara <k.hara.pg gmail.com> 2014-04-02 20:22:40 PDT ---
New pull request:
https://github.com/D-Programming-Language/dmd/pull/3416

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 02 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|implicit overload merging   |implicit overload merging
                   |with selective/renamed      |with selective imports
                   |imports should be removed   |should be removed


--- Comment #9 from Kenji Hara <k.hara.pg gmail.com> 2014-04-06 21:22:13 PDT ---
Very sorry, I was misused the word "renamed imports" for the feature "selective
imports with renaming selected symbols".

I tweak the issue summary.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 06 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359



--- Comment #10 from Kenji Hara <k.hara.pg gmail.com> 2014-04-06 21:40:13 PDT
---
The negative effect of the implicit alias is that it makes selective imports
and basic imports unexchangeable. For example:

module a;
auto foo(int[] ) { return 2; }

module b;
import a;  // [A]
auto foo(long[] ) { return 1; }
void main()
{
    assert(foo([1,2]) == 1);
}

At the line [A], the basic import makes b.foo visible, but it is hidden by
b.foo. Therefore foo([1,2]) in main will call b.foo properly.

Next, what's will occur if you replace `import a;` to `import a : foo`?

import a : foo;  // [A2]
auto foo(long[] ) { return 1; }

The selected a.foo is *implicitly* added in the overload set of b.foo, then
foo([1,2]) will match a.foo(int[] ) more better than b.foo(long[] ), and the
assertion in main will fail in runtime.

I think this is much non-intuitive behavior. No one would expect the silent
code breaking in module b.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 06 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12359


Martin Nowak <code dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code dawg.eu


--- Comment #11 from Martin Nowak <code dawg.eu> 2014-04-06 22:28:26 PDT ---
(In reply to comment #10)
 I think this is much non-intuitive behavior. No one would expect the silent
 code breaking in module b.

I do agree with the diagnosis but we absolutely need a proper upgrade plan. I know it's tricky, but we need a warning for code that relies on the implicit alias without affecting code that just uses the imported symbol. First of all you want to reach a consensus on the topic though. I haven't yet seen any good argument in favor of the current behavior, still it's used quite deliberately in many places.
 They are just funny ideas to mask fully qualified names.

Fully qualified names hardly do any harm, except for rare cases where a package name collides with a rename. So maybe a syntax isn't necessary. import core = core.win; -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 06 2014