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