Thread overview
[Issue 2529] New: 'package' access qualifier should allow access to sub-packages
Dec 21, 2008
d-bugmail
Jan 02, 2009
d-bugmail
Mar 15, 2009
d-bugmail
Aug 04, 2010
Don
Aug 06, 2010
Don
Jan 24, 2013
Andrej Mitrovic
Jan 24, 2013
Andrej Mitrovic
December 21, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2529

           Summary: 'package' access qualifier should allow access to sub-
                    packages
           Product: D
           Version: 1.037
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: spec
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: jarrett.billingsley@gmail.com


Currently, a symbol declared as package in "a.b" is only accessible to other modules in "a", such as "a.c" and "a.d".  But it is not accessible from "a.sub.x".

The language spec is somewhat unclear on this:

http://www.digitalmars.com/d/1.0/attribute.html

"Package extends private so that package members can be accessed from code in other modules that are in the same package. This applies to the innermost package only, if a module is in nested packages. "

What I find unclear is "other modules in the same package."  I see "a.sub.x" as in the same package as "a.b", since they're both in "a".

What would this be useful for?  Well as a practical example, I've been working on the new implementation of MiniD for several months, and as the codebase has grown, I've accumulated more and more modules.  Now that I have close to 50 modules in one package, I'd like to put them in sub-packages of related functionality.

The problem is that there is a small set of "universal" functionality which is needed by the entire library but which I don't want to be accessible from outside the library.  I can't make it private since then it won't be accessible from other modules in the library.  I can't make it public because then it would be accessible from outside the library.  So I'm stuck with package, but the problem with that is that only modules with the _exact_ same package prefix as the common functionality can access it.  Thus, all of my modules are forced into the same package.

What I am proposing is that the "package" qualifier's meaning of "other modules in the same package" be defined to be "other modules in the same package, including those in subpackages."  This does not actually even require a spec change, since this new behavior is consistent with what is stated.  It also does not break any code, is a simple fix, and without it, I can see a lot of D libraries and programs being forced into this kind of one-level hierarchy.


-- 

January 02, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2529





------- Comment #1 from clugdbug@yahoo.com.au  2009-01-02 05:03 -------
I would actually want this to work the other way. I'd like a.sub.x to be accessible from a.b. Eg database.mysql should be able to use database.internal.sqlparsing, rather than the other way around. It would seem wrong to have the lowest-level stuff in the root.

But I agree that the existing 'package' semantics force you to a flat hierarchy.


-- 

March 15, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=2529





------- Comment #2 from daniel.keep+d.puremagic.com@gmail.com  2009-03-15 18:56 -------
(In reply to comment #1)

Perhaps we need two changes to the current behaviour:

1. package access applies to sub-packages as well.

2. The package protection attribute accepts an optional argument which specifies the base package which has access.  In Don's example:

module database.internal.sqlparsing;
package(database) void foo();

This would allow anything under the database package access to foo.


-- 

August 04, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=2529


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #3 from Don <clugdbug@yahoo.com.au> 2010-08-04 05:56:19 PDT ---
IMHO, this bug should be closed as invalid, because the initial suggestion in the bug report is completely wrong: it would drive you to put low-level stuff in the root, and derived stuff in the leaves. Implementing that suggestion would encourage poor design.

The current behaviour of 'package' in D seems nearly identical to the one in Java. Java has the same problem.

Here is a Java proposal to fix the problem, which was ultimately rejected.

http://jcp.org/en/jsr/detail?id=294

"Today designers are forced to declare elements of the program that are needed
by other subparts of the implementation as public - thereby making them
globally accessible, which is clearly suboptimal.
Alternately, the entire implementation can be placed in a single package. This
resolves the issue above, but is unwieldy, and exposes all internals of all
subparts to each other. "

I also found this link to be helpful:

http://stackoverflow.com/questions/403583/what-is-the-use-of-package-level-protection-in-java

---
I can't really escape the feeling that 'package' is a bit of a flawed concept. The problems with it don't seem easy to fix.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 06, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=2529



--- Comment #4 from Don <clugdbug@yahoo.com.au> 2010-08-06 07:15:42 PDT ---
Having thought about this a bit more, I think that a much better approach would be a property applied to module declaration.

@internal
module cleverdb.mysql.funkystuff;

The property would mean, this module can only be imported from modules in cleverdb.*

Then, everything in that module could be made public to the hierarchy, without exposing it to the whole world. Thus, some level of encapsulation would be preserved.

That's not an actual proposal, the point is just that closing this bug would not mean that the original use case would never be addressed: there are other possible solutions without changing the meaning of 'package'.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 24, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=2529


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

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


--- Comment #5 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-01-23 18:00:14 PST ---
(In reply to comment #3)
> IMHO, this bug should be closed as invalid, because the initial suggestion in the bug report is completely wrong: it would drive you to put low-level stuff in the root, and derived stuff in the leaves. Implementing that suggestion would encourage poor design.

Agreed, applies to D2 now as well.

Also, package can actually be abused because it doesn't apply to actual folders, it only applies to module declarations. This means you can fake your way into getting access simply by re-creating the package folder structure and use an import switch to introduce the new modules:

/a/m.d:
module a.m;
package void foo() { }

/a/user/a/workaround.d:
module a.workaround;
import a.m;
auto foo()
{
    return a.m.foo();  // free access!
}

/a/user/main.d:
module main;
import a.workaround;
void main()
{
    foo();
}

$ rdmd user\main.d -Iuser

No compile errors!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 24, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=2529



--- Comment #6 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-01-23 18:02:19 PST ---
(In reply to comment #5)

> /a/user/a/workaround.d:

Should be /user/a/workaround.d

> /a/user/main.d:

Should be /user/main.d

Anyway I'm filing this as another bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------