www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 316] New: No way to selectively expose imported symbols

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

           Summary: No way to selectively expose imported symbols
           Product: D
           Version: 0.163
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: sean f4.ca


(Copied from digitalmars.D so it isn't forgotten.  According to a later comment
by Walter, the current behavior a compiler bug.)


Consider this code:

    module a;

    void afn1() {}
    void afn2() {}
--------
    module b;

    public import a;

    void bfn1() {}
--------
    module main;

    import a;
    import b;

    void main()
    {
        afn1();
        afn2();
        bfn1();
    }

This is the classic method of exposing symbols from a to users who import b. 
In this case let's assume that b uses some aspects of a and it's unreasonable
to expect the user to import a just to use b.  So far so good.  But what if a
is a large module and the programmer doesn't want to expose all of a through b?
 Using the new import features, one might assume that it is possible to change
b to this:

    module b;

    public import a : afn1;

    void bfn1() {}

However, doing so results in this compile error:

    C:\code\src\d\test>dmd main a b
    a.d(3): function a.afn1 conflicts with b.afn1 at b.d(3)

I suppose this should be expected as the old private import + alias method
would have produced the same error, but it's still irritating. Now what if we
make the import private:

    module b;

    private import a : afn1;

    void bfn1() {}

This results in the same compile error as public import:

    C:\code\src\d\test>dmd main a b
    a.d(3): function a.afn1 conflicts with b.afn1 at b.d(3)

The error with private imports is to be expected given the lookup rules in D,
but it's worth noting nevertheless.  So at this point I must conclude that,
given the current implementation:

    * Selective public import is useless for library developers.
      Renaming symbols in this case defeats the purpose of publicly
      importing, and it is unreasonable to assume that the user will not
      import both a and b in his own code.

    * Selective private import is useless for library developers without
      diligent and careful use of the renaming feature, because the risk
      of symbol collisions is not only just as great as with public
      import, but the fact that the import is private actually increases
      the likelihood that the user will import both a and b in his own
      code.

The simplest solution would be to change selective import to not bind the
symbols into the current namespace, thus keeping the symbols as "second class
citizens."  This would have the following effect:

    import std.stdio : writef;

Import one symbol, writef, as a second-class citizen for the current module.

    static import std.stdio : writef;

Make the symbol 'writef' available to the current module via its fully
qualified name only.

    import std.stdio : writef = writef;

Import only writef from std.stdio and bind it into the current scope. This
would be equivalent to the current behavior of the non-renaming selective
import.  Thus, currently, these two lines are identical:

    static import std.stdio : writef;
    import std.stdio : writef;

But under the new method, these two lines would be identical:

    static import std.stdio : writef = writef;
    import std.stdio : writef = writef;

This should be obvious, as the "= writef" suggests binding the symbol into the
current scope using the name "writef".  Please note that:

    import std.stdio : writef = writef;

Should not create a "second class" lookup table for the symbol, "writef", as
the "= writef" is present.  If both the binding and second-class lookup is
desired, a two-line approach may be used:

    import std.stdio : writef;
    alias std.stdio.writef writef;


-- 
Sep 01 2006
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=316


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WORKSFORME




------- Comment #1 from bugzilla digitalmars.com  2006-09-19 15:23 -------
Not reproducible with DMC 0.167.


-- 
Sep 19 2006