Module system of D2: to be fixed still

Denis Koroskin 2korden at gmail.com
Wed Apr 22 04:45:20 PDT 2009


On Wed, 22 Apr 2009 12:55:44 +0400, bearophile <bearophileHUGS at lycos.com> wrote:

> The current module&package system of D2 needs to be fixed, it has some  
> conceptual/semantic/logic holes. It looks like the result a good design  
> stopped mid-way.
>
> I have discussed them three times in the past, and now that Phobos2 is  
> mostly here and only a better support for multi-threading programming is  
> planned to be added to D2, it's a good moment to list all the troubles  
> with the module&package system, and to fix the current half-backed and  
> partially broken/illogical situation.
> I'll remind this few months from now again if in the meantime things  
> have not improved yet.
>
> Thank you,
> bearophile

What I see is wrong/incomplete/needs to be fixed in current system:

1) The most important thing that needs to be fixed is package implying final.

private, protected, public and package should only affect name visibility. It should be *completely* orthogonal to virtual and final. But currently, whenever I make a method package (so that it would be only accessible from that package), I can't override it anymore - the method is automatically made final and non-overridable.

The current state of "package" attribute makes me *very angry* to say politely, because I'm forced to make many of my methods public whereas they never should be accessible to end user.

2) There is no easy way to define a symbol (a member function, for example) and implement it in another one. Here is an example:

module Foo;

enum Bar {
    Bar1,
    Bar2,
}

class Foo
{
    void doSomethingPlatformSpecific(Bar bar);
}

I'd like to implement doSomethingPlatformSpecific in separate modules:

Foo_win32.d - win32 implementation
FOo_linux.d - linux implementation

First, I can't import Foo, because it will lead to name collision. It means that I have no access to enum Bar and its elements.
Duplicating it wrong, wrong, wrong, because now I have to maintain 3 (and, possibly, more in future) files that contain Bar.
More over, this will lead to linking errors if Foo.d and Foo_win32.d linked together (because both contain enum Bar). So I have to exclude Foo.d from compilation.
This is very frustrating, and the only alternative here is as follows:

extern(C) _doSomethingPlatformSpecific(Bar bar); // implemented somewhere else

class Foo
{
    void doSomethingPlatformSpecific(Bar bar)
    {
        _doSomethingPlatformSpecific(bar);
    }
}

It works actually, but now I loose parameters type safety - whenever I add new parameters (or change existing ones) and forget to update implementations, I won't get any linking errors, only access violations on runtime.

3) I miss package friendship:

# module ui.controls.Control;
#
# // Example 1:
# friend modile ui.widgets.Widget;
# // all the contents of this module are accessible to ui.widgets.Widget
#
# // Example 2:
# friend package ui.widgets;
# // all the contents of this module are accessible to ui.widgets.*
#

I would make my code a lot simpler in many cases.

That's all for now. I'll add to this list once I recall other issues.



More information about the Digitalmars-d mailing list