www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Module system of D2: to be fixed still

reply bearophile <bearophileHUGS lycos.com> writes:
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
Apr 22 2009
next sibling parent davidl <davidl nospam.org> writes:
ÔÚ Wed, 22 Apr 2009 16:55:44 +0800ŁŹbearophile <bearophileHUGS lycos.com>  
ĐŽ”À:

 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

Yes, the package does not offer us enough functionalities. However, only saying "I have discussed/talked/stated/complained something XXX times" does nothing good to the current state. Contrarily, I prefer one list the reasons of why current one is broken and corresponding sophisticated solutions. If the proposer himself didn't get any sound plan, then he'd better raise an open question in this newsgroup. I also have missed your discussions about the package system as some other D users. What are they? For me, I find the following questionable parts: 1. loose the restriction of same package accessing of private members. If I remember correctly, MiniD suffers from it and that disallow MiniD source to be organized in a better way. But I doubt if the restriction were lifted, current private qualifier will become very restrictive useful. e.g. In package: mylib.Framework.GUI class "Widget" may have some private members don't want to be accessible by mylib.Framework.GUI.Dialog 2. The diagnose message does very little help. 3. There are some bizarre compiler bugs. e.g. http://d.puremagic.com/issues/show_bug.cgi?id=1592
Apr 22 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 22 Apr 2009 12:55:44 +0400, bearophile <bearophileHUGS 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.
Apr 22 2009
prev sibling parent reply grauzone <none example.net> writes:
Ah, the monthly bearophile modules-must-be-fixed thread. (It was only 
three times?)

Here are my ideas/concerns:
- the current import semantics should be redone such that "import 
a.b.c.d;" works like "import d = a.b.c.d;", and add a new syntax like 
"import a.b.c.d.*;" to get the current behavior
- allow to import all modules of a package at once ("import a.b.c.*;")
- allow a shorter syntax to import several modules from the same package 
("import a.b.{c, c2, c3};" or similar)
- fix the enum circular dependency bug PRETTY PLEASE 
http://d.puremagic.com/issues/show_bug.cgi?id=1160
- the package attribute must be fixed, goddamn (see Koroskin's post) (oh 
hey, at least it should raise an error when using the override attribute)
Apr 22 2009
parent reply Leandro Lucarella <llucax gmail.com> writes:
grauzone, el 22 de abril a las 18:58 me escribiste:
 Ah, the monthly bearophile modules-must-be-fixed thread. (It was only three
times?)
 
 Here are my ideas/concerns:
 - the current import semantics should be redone such that "import
   a.b.c.d;" works like "import d = a.b.c.d;", and add a new syntax like
   "import a.b.c.d.*;" to get the current behavior

Shouldn't be static import a.b.c.d;? It's a little odd to get imported just the last part. I'm not convinced though.
 - allow to import all modules of a package at once ("import a.b.c.*;")

That's a good idea. The same question as about, if there are a.b.c.d, this should add a.b.c.d or simply d to the current symbols?
 - allow a shorter syntax to import several modules from the same package
("import a.b.{c, c2, c3};" or similar)

What about the standard syntax: import a.b: c, c2, c3;? I don't know if that works for modules, though, but I think the syntax can be extended to allow that. -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- En la calle me crucĂ© con un señor muy correcto, que habitualmente anda en Falcon; iba corriendo con dos valijas en la mano y dijo: "Voy para Miami, tiene algĂșn mensaje o ..." y le dije: "No, no, no..." -- Extra Tato (1983, Triunfo de AlfonsĂ­n)
Apr 22 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
Leandro Lucarella:
 grauzone:
 - the current import semantics should be redone such that "import
   a.b.c.d;" works like "import d = a.b.c.d;", and add a new syntax like
   "import a.b.c.d.*;" to get the current behavior

Shouldn't be static import a.b.c.d;? It's a little odd to get imported just the last part. I'm not convinced though.

davidl:
Yes, the package does not offer us enough functionalities. However, only saying
"I have discussed/talked/stated/complained something XXX times" does nothing
good to the current state. Contrarily, I prefer one list the reasons of why
current one is broken and corresponding sophisticated solutions.<

I can answer both, adding a small change from what I have said last time :-) import foo; Imports in the current namespace the "foo" module name. import foo: *; Imports in the current namespace all the names inside foo, but not the "foo" module name itself. import foo: bar, baz; Imports in the current namespace the "bar" and "baz" names, but not the "foo" module name. bar and baz can be anything, packages too. Bye, bearophile
Apr 22 2009
parent Georg Wrede <georg.wrede iki.fi> writes:
bearophile wrote:
 Leandro Lucarella:
 grauzone:
 - the current import semantics should be redone such that "import
   a.b.c.d;" works like "import d = a.b.c.d;", and add a new syntax like
   "import a.b.c.d.*;" to get the current behavior

just the last part. I'm not convinced though.

davidl:
 Yes, the package does not offer us enough functionalities. However,
 only saying "I have discussed/talked/stated/complained something XXX
 times" does nothing good to the current state. Contrarily, I prefer
 one list the reasons of why current one is broken and corresponding
 sophisticated solutions.

I can answer both, adding a small change from what I have said last time :-) import foo; Imports in the current namespace the "foo" module name. import foo: *; Imports in the current namespace all the names inside foo, but not the "foo" module name itself. import foo: bar, baz; Imports in the current namespace the "bar" and "baz" names, but not the "foo" module name. bar and baz can be anything, packages too.

It's a shame that I never took a combinatorics course. This whole issue looks like a homework assignment from the second semester: "(0) Enumerate the set of use cases for importing source code modules. (1) Outline the minimum amount of directed graphs that covers all these use cases. (2) Either prove that circular graphs are unavoidable, or show how they can be avoided with a standard transform." etc. At any rate, we should totally avoid discussing syntax *until* we have come up with the requirements that are needed. There's no use in cluttering the discussion with syntax while we aren't clear on exactly what is needed (and what is not needed). Oh, and for clarity, we probably should define Circular as a mutual or an a->b->c->a dependency. The case a->b->d + a->c->d is, IMHO not Circular. It should have some other name, to avoid confusion. As for Friend modules, these might arise when a library includes (for the sake of practicality) sub-modules. Can the library programmer be required to refactor the Friend needs to a new module that the other two both import? A library with a main and sub modules, where the sub modules may be individually imported (as in std.c.whatever), seems to impy that importing the sub module does not necessitate making the main module visible. It seems to merely be a path component in finding the sub module. Probably this should be the norm. (Just scratching the top of the iceberg here.)
Apr 23 2009