www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Re: QtD 0.1 is out!

reply Eldar Insafutdinov <e.insafutdinov gmail.com> writes:
We faced a bug that module static constructors don't work with cyclic imports.
Currently it's fixed with a dirty hack which is not really acceptable. Is there
any chance for this to be fixed?
Feb 27 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Feb 27, 2009 at 12:36 PM, Eldar Insafutdinov
<e.insafutdinov gmail.com> wrote:
 We faced a bug that module static constructors don't work with cyclic imports.
Currently it's fixed with a dirty hack which is not really acceptable. Is there
any chance for this to be fixed?

I'll save Walter the trouble: come up with a reproduceable testcase if you haven't already. It won't get fixed it he can't tell what the problem is.
Feb 27 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jarrett Billingsley wrote:
 On Fri, Feb 27, 2009 at 12:36 PM, Eldar Insafutdinov 
 <e.insafutdinov gmail.com> wrote:
 We faced a bug that module static constructors don't work with
 cyclic imports. Currently it's fixed with a dirty hack which is not
 really acceptable. Is there any chance for this to be fixed?
 

I'll save Walter the trouble: come up with a reproduceable testcase if you haven't already. It won't get fixed it he can't tell what the problem is.

I'll add to that my experience is that if the test case is incomplete, then I need to guess at the rest and fill it in. Often, then the test case works, and there's a cycle of "I can't reproduce the problem" followed by the missing bit of context that was the real cause. Then once the problem gets fixed, the reproducible test case goes into the test suite so it stays fixed.
Feb 27 2009
parent reply Eldar Insafutdinov <e.insafutdinov gmail.com> writes:
Walter Bright Wrote:

 Jarrett Billingsley wrote:
 On Fri, Feb 27, 2009 at 12:36 PM, Eldar Insafutdinov 
 <e.insafutdinov gmail.com> wrote:
 We faced a bug that module static constructors don't work with
 cyclic imports. Currently it's fixed with a dirty hack which is not
 really acceptable. Is there any chance for this to be fixed?
 

I'll save Walter the trouble: come up with a reproduceable testcase if you haven't already. It won't get fixed it he can't tell what the problem is.

I'll add to that my experience is that if the test case is incomplete, then I need to guess at the rest and fill it in. Often, then the test case works, and there's a cycle of "I can't reproduce the problem" followed by the missing bit of context that was the real cause. Then once the problem gets fixed, the reproducible test case goes into the test suite so it stays fixed.

I'm sorry, my mistake - it's in specs http://www.digitalmars.com/d/1.0/module.html
Cycles (circular dependencies) in the import declarations are allowed as long 
as not both of the modules contain static constructors or static destructors. 
Violation of this rule will result in a runtime exception.

Now we have to make a manual init function called from class constructors. I understand that allowing static consructors with cyclic imports will make order of their execution undefined, but this is acceptable and actually semantically doesn't break the idea of cyclic imports. Otherwise in my opinion this behavior is inconsistent..
Feb 27 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Eldar Insafutdinov wrote:
 Now we have to make a manual init function called from class
 constructors. I understand that allowing static consructors with
 cyclic imports will make order of their execution undefined, but this
 is acceptable and actually semantically doesn't break the idea of
 cyclic imports. Otherwise in my opinion this behavior is
 inconsistent..

One of the goals of D is to eliminate undefined behavior wherever possible. In C++, the undefined order of static construction was a source of many porting problems. I think it's better in the long run to have a defined order, even if it means having to reorganize the code a bit.
Feb 27 2009
next sibling parent reply Eldar Insafutdinov <e.insafutdinov gmail.com> writes:
Walter Bright Wrote:

 Eldar Insafutdinov wrote:
 Now we have to make a manual init function called from class
 constructors. I understand that allowing static consructors with
 cyclic imports will make order of their execution undefined, but this
 is acceptable and actually semantically doesn't break the idea of
 cyclic imports. Otherwise in my opinion this behavior is
 inconsistent..

One of the goals of D is to eliminate undefined behavior wherever possible. In C++, the undefined order of static construction was a source of many porting problems. I think it's better in the long run to have a defined order, even if it means having to reorganize the code a bit.

in our case resources we are initializing are unrelated to the modules we are importing. and semantically the code is placed in modules as it should be.
Feb 27 2009
parent Walter Bright <newshound1 digitalmars.com> writes:
Eldar Insafutdinov wrote:
 in our case resources we are initializing are unrelated to the
 modules we are importing. and semantically the code is placed in
 modules as it should be.

True, often there isn't an actual dependency on the order, but the compiler can't tell that.
Feb 27 2009
prev sibling parent reply Fawzi Mohamed <fmohamed mac.com> writes:
On 2009-02-27 21:10:29 +0100, Walter Bright <newshound1 digitalmars.com> said:

 Eldar Insafutdinov wrote:
 Now we have to make a manual init function called from class
 constructors. I understand that allowing static consructors with
 cyclic imports will make order of their execution undefined, but this
 is acceptable and actually semantically doesn't break the idea of
 cyclic imports. Otherwise in my opinion this behavior is
 inconsistent..

One of the goals of D is to eliminate undefined behavior wherever possible. In C++, the undefined order of static construction was a source of many porting problems. I think it's better in the long run to have a defined order, even if it means having to reorganize the code a bit.

I fully agree, circular dependencies between modules is in general a good practice: a circular dependency it means that you have tight coupling, in in that case it is normally better to have everything in the same module to have a better control on it. Sometime one has cases in which circular dependencies arise, two ways to get rid of them are for example: 1) define and interface, the circular dependency is in the interfaces that are described in the same module, the two (or more) modules include the interfaces, and are not directly dependent on each other (only through the interfaces) 2) use templates, the circular dependencies are on a template parameter. The circular dependencies arise only upon instantiation
Feb 27 2009
parent reply Fawzi Mohamed <fmohamed mac.com> writes:
On 2009-02-27 21:49:58 +0100, Fawzi Mohamed <fmohamed mac.com> said:

 On 2009-02-27 21:10:29 +0100, Walter Bright <newshound1 digitalmars.com> said:
 
 Eldar Insafutdinov wrote:
 Now we have to make a manual init function called from class
 constructors. I understand that allowing static consructors with
 cyclic imports will make order of their execution undefined, but this
 is acceptable and actually semantically doesn't break the idea of
 cyclic imports. Otherwise in my opinion this behavior is
 inconsistent..

One of the goals of D is to eliminate undefined behavior wherever possible. In C++, the undefined order of static construction was a source of many porting problems. I think it's better in the long run to have a defined order, even if it means having to reorganize the code a bit.

I fully agree,

 circular dependencies between modules is in general a good practice:
 a circular dependency it means that you have tight coupling, in in that 
 case it is normally better to have everything in the same module to 
 have a better control on it.
 Sometime one has cases in which circular dependencies arise, two ways 
 to get rid of them are for example:
 
 1) define and interface, the circular dependency is in the interfaces 
 that are described in the same module, the two (or more) modules 
 include the interfaces, and are not directly dependent on each other 
 (only through the interfaces)
 
 2) use templates, the circular dependencies are on a template 
 parameter. The circular dependencies arise only upon instantiation

Feb 27 2009
parent reply Yigal Chripun <yigal100 gmail.com> writes:
Fawzi Mohamed wrote:
 On 2009-02-27 21:49:58 +0100, Fawzi Mohamed <fmohamed mac.com> said:

 On 2009-02-27 21:10:29 +0100, Walter Bright
 <newshound1 digitalmars.com> said:

 Eldar Insafutdinov wrote:
 Now we have to make a manual init function called from class
 constructors. I understand that allowing static consructors with
 cyclic imports will make order of their execution undefined, but this
 is acceptable and actually semantically doesn't break the idea of
 cyclic imports. Otherwise in my opinion this behavior is
 inconsistent..

One of the goals of D is to eliminate undefined behavior wherever possible. In C++, the undefined order of static construction was a source of many porting problems. I think it's better in the long run to have a defined order, even if it means having to reorganize the code a bit.

I fully agree,

 circular dependencies between modules is in general a good practice:
 a circular dependency it means that you have tight coupling, in in
 that case it is normally better to have everything in the same module
 to have a better control on it.
 Sometime one has cases in which circular dependencies arise, two ways
 to get rid of them are for example:

 1) define and interface, the circular dependency is in the interfaces
 that are described in the same module, the two (or more) modules
 include the interfaces, and are not directly dependent on each other
 (only through the interfaces)

 2) use templates, the circular dependencies are on a template
 parameter. The circular dependencies arise only upon instantiation


I agree with the above but there is still a small issue here: A module is a single file and when you have several large classes that are tightly coupled you can get a very big file with thousands of lines. what if i want to put each class in its own file? besides, the notion of a module is somewhat redundant - it's functionally a static struct. this is related to D's compilation model which is copied from C/C++ and it seems to me that this model is outdated. C#'s model of assemblies and metadata seems more capable. for instance there's no need for header files, that info is stored in the metadata of the assembly.
Feb 28 2009
next sibling parent reply Yigal Chripun <yigal100 gmail.com> writes:
Jarrett Billingsley wrote:
 On Sat, Feb 28, 2009 at 11:05 AM, Yigal Chripun<yigal100 gmail.com>  wrote:
 I agree with the above but there is still a small issue here:
 A module is a single file and when you have several large classes that are
 tightly coupled you can get a very big file with thousands of lines. what if
 i want to put each class in its own file?
 besides, the notion of a module is somewhat redundant - it's functionally a
 static struct.

 this is related to D's compilation model which is copied from C/C++ and it
 seems to me that this model is outdated. C#'s model of assemblies and
 metadata seems more capable. for instance there's no need for header files,
 that info is stored in the metadata of the assembly.

Preciiiisely. I've been toying with the concept of a compiler which doesn't actually emit object files until it has to link its code into some form of executable. Instead it produces these sort of platform-independent internal representation files, which can contain all the metadata and symbol information needed. They can be as small as a single module or as large as an entire multi-level package. It sounds a lot like the model C# has adopted.

I also think that source code organization should be orthogonal to the organization of the deployment executables (assemblies in .net) something simillar to namespaces in C#. other useful metadata to include in those files is the documantation and versioning info.
Feb 28 2009
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Yigal Chripun wrote:
 On Sat, Feb 28, 2009 at 11:05 AM, Yigal Chripun<yigal100 gmail.com> 
 wrote:
 I agree with the above but there is still a small issue here:
 A module is a single file and when you have several large classes
 that are
 tightly coupled you can get a very big file with thousands of lines.
 what if
 i want to put each class in its own file?
 besides, the notion of a module is somewhat redundant - it's
 functionally a
 static struct.



You can do this with mixins or aliases. Honestly, something I'd like to see is to extend the import syntax to allow you to import symbols from other symbols. For example:
 module foo;

 struct bar
 {
   static void baz();
 }

 module main;

 import foo.bar;

 void main() { baz(); }

 this is related to D's compilation model which is copied from C/C++
 and it
 seems to me that this model is outdated. C#'s model of assemblies and
 metadata seems more capable. for instance there's no need for header
 files,
 that info is stored in the metadata of the assembly.



Given that D name mangling contains most if not all of a function's interface, it sometimes makes me wonder why we can't just import a .lib file. Heck, stick an extra symbol on the end called _D_Interface if you must. :)
 I also think that source code organization should be orthogonal to the
 organization of the deployment executables (assemblies in .net)
 something simillar to namespaces in C#.

There are times where I hate this. The problem is that this seems to encourage very flat hierarchies in .NET code, with everything jammed together. What really exacerbates the situation is that namespaces can be added to by any library at any time. For example, I had some code in C#, and I couldn't for the life of me figure out what I was supposed to link to. Because the examples had multiple libraries all dumping their stuff into the same namespace, it was impossible to work out where any given symbol was coming from. I ended up having to manually go through every goddamn library with the object browser to figure it out. Enforcing the module<->file thing can be annoying at times, but nowhere near as bad as having no indication whatsoever where something is defined. -- Daniel
Feb 28 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Yigal Chripun wrote:
 this is related to D's compilation model which is copied from C/C++ and 
 it seems to me that this model is outdated. C#'s model of assemblies and 
 metadata seems more capable. for instance there's no need for header 
 files, that info is stored in the metadata of the assembly.

D can do the same thing - it can use the source of the module directly, or it can use a hand-generated 'header' file, or an automatically generated 'header' file. The latter is semantically indistinguishable from compiling the source module to a "metadata" file. I originally considered having D write such a "metadata" file, until I realized I didn't have to invent a format and a writer and reader for that format. I could just use the D source code notation as a "metadata" file and reuse the existing code.
Feb 28 2009
parent reply Don <nospam nospam.com> writes:
Walter Bright wrote:
 Yigal Chripun wrote:
 this is related to D's compilation model which is copied from C/C++ 
 and it seems to me that this model is outdated. C#'s model of 
 assemblies and metadata seems more capable. for instance there's no 
 need for header files, that info is stored in the metadata of the 
 assembly.

D can do the same thing - it can use the source of the module directly, or it can use a hand-generated 'header' file, or an automatically generated 'header' file. The latter is semantically indistinguishable from compiling the source module to a "metadata" file. I originally considered having D write such a "metadata" file, until I realized I didn't have to invent a format and a writer and reader for that format. I could just use the D source code notation as a "metadata" file and reuse the existing code.

The D system has a major limitation, though -- you can't split the source for a module across multiple files. Which pushes you towards enormous source files. It's more restricted than both C# and C++ in this respect.
Mar 01 2009
parent Christopher Wright <dhasenan gmail.com> writes:
Jarrett Billingsley wrote:
 On Sun, Mar 1, 2009 at 10:16 AM, Don <nospam nospam.com> wrote:
 The D system has a major limitation, though -- you can't split the source
 for a module across multiple files. Which pushes you towards enormous source
 files. It's more restricted than both C# and C++ in this respect.

Yeah. Imagine if DMDFE were written in D; how big would those modules have to be?

The current organization of DMDFE is totally inconducive to D's module system, which I find ironic.
Mar 01 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Feb 27, 2009 at 5:07 PM, Walter Bright
<newshound1 digitalmars.com> wrote:
 Eldar Insafutdinov wrote:
 in our case resources we are initializing are unrelated to the
 modules we are importing. and semantically the code is placed in
 modules as it should be.

True, often there isn't an actual dependency on the order, but the compiler can't tell that.

I was going to say "can't it?" but then remembered separate compilation. Sigh. I think the separate compilation paradigm, at least as designed for C and C++, has to go the way of the dodo for lots of cool things to be made possible. The thread on .D about not being able to non-virtualize methods in the face of separate compilation is another example.
Feb 27 2009
prev sibling next sibling parent reply Lars Ivar Igesund <larsivar igesund.net> writes:
Eldar Insafutdinov wrote:

 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?

IMO it is the cyclic import that is the bug ;) -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Feb 28 2009
next sibling parent reply grauzone <none example.net> writes:
Lars Ivar Igesund wrote:
 Eldar Insafutdinov wrote:
 
 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?

IMO it is the cyclic import that is the bug ;)

Maybe all cyclic dependency bugs are on purpose, to teach people not to use this evil D feature? Yeah, that must it be. I can't explain why else these bugs/issues aren't fixed, and why people only reply with incredibly useful statements like "but you shouldn't use this feature anyway!". Broken features should be either fixed or removed. This half-assedness about it isn't really going to help D.
Feb 28 2009
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
grauzone wrote:

 Lars Ivar Igesund wrote:
 Eldar Insafutdinov wrote:
 
 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?

IMO it is the cyclic import that is the bug ;)

Maybe all cyclic dependency bugs are on purpose, to teach people not to use this evil D feature? Yeah, that must it be. I can't explain why else these bugs/issues aren't fixed, and why people only reply with incredibly useful statements like "but you shouldn't use this feature anyway!". Broken features should be either fixed or removed. This half-assedness about it isn't really going to help D.

Well it's about cyclic dependency of initialization via module constructors only right? Cyclic imports in general aren't (supposed to be) broken, nor are module constructors.
Feb 28 2009
next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Lutger wrote:
 grauzone wrote:
 
 Lars Ivar Igesund wrote:
 Eldar Insafutdinov wrote:

 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?


use this evil D feature? Yeah, that must it be. I can't explain why else these bugs/issues aren't fixed, and why people only reply with incredibly useful statements like "but you shouldn't use this feature anyway!". Broken features should be either fixed or removed. This half-assedness about it isn't really going to help D.

Well it's about cyclic dependency of initialization via module constructors only right? Cyclic imports in general aren't (supposed to be) broken, nor are module constructors.

Additionally, the compiler has sufficient information to complain about the problem at compile time, but it doesn't. That is a bug.
Feb 28 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Christopher Wright wrote:
 Additionally, the compiler has sufficient information to complain about 
 the problem at compile time, but it doesn't. That is a bug.

No, it does not. The compiler doesn't know about private imports of separately compiled modules.
Feb 28 2009
next sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jarrett Billingsley wrote:
 See it's funny, since in the other post, you said that using an
 autogenerated header file is semantically indistinguishable from
 compiling it to a metadata file.  And here you're pointing out an
 obvious shortcoming!

You can make hand-generated ones, too. The idea of keeping private imports private is to explicitly *avoid* dependencies on knowing the contents. It's a principle of encapsulization.
Feb 28 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter Bright wrote:
 Jarrett Billingsley wrote:
 See it's funny, since in the other post, you said that using an
 autogenerated header file is semantically indistinguishable from
 compiling it to a metadata file.  And here you're pointing out an
 obvious shortcoming!

You can make hand-generated ones, too. The idea of keeping private imports private is to explicitly *avoid* dependencies on knowing the contents. It's a principle of encapsulization.

encapsuli...what? I definitedly need to conceptify that one :o). Andrei
Feb 28 2009
parent Derek Parnell <derek psych.ward> writes:
On Sat, 28 Feb 2009 13:03:05 -0800, Andrei Alexandrescu wrote:

 Walter Bright wrote:
 Jarrett Billingsley wrote:
 See it's funny, since in the other post, you said that using an
 autogenerated header file is semantically indistinguishable from
 compiling it to a metadata file.  And here you're pointing out an
 obvious shortcoming!

You can make hand-generated ones, too. The idea of keeping private imports private is to explicitly *avoid* dependencies on knowing the contents. It's a principle of encapsulization.

encapsuli...what? I definitedly need to conceptify that one :o).

I think the word Walter was reaching for was "encapsulement" ;-) -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Feb 28 2009
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Walter Bright wrote:
 Christopher Wright wrote:
 Additionally, the compiler has sufficient information to complain 
 about the problem at compile time, but it doesn't. That is a bug.

No, it does not. The compiler doesn't know about private imports of separately compiled modules.

Okay, the compiler could gain that information, but it does not, since it is not required. In many cases, the compiler could detect these issues. Detecting these would be a reasonable, if low priority, enhancement.
Feb 28 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Christopher Wright wrote:
 Walter Bright wrote:
 Christopher Wright wrote:
 Additionally, the compiler has sufficient information to complain 
 about the problem at compile time, but it doesn't. That is a bug.

No, it does not. The compiler doesn't know about private imports of separately compiled modules.

Okay, the compiler could gain that information, but it does not, since it is not required. In many cases, the compiler could detect these issues. Detecting these would be a reasonable, if low priority, enhancement.

The problem if it detects it in an implementation-defined manner is the source code is no longer portable.
Feb 28 2009
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Walter Bright wrote:
 Christopher Wright wrote:
 Walter Bright wrote:
 Christopher Wright wrote:
 Additionally, the compiler has sufficient information to complain 
 about the problem at compile time, but it doesn't. That is a bug.

No, it does not. The compiler doesn't know about private imports of separately compiled modules.

Okay, the compiler could gain that information, but it does not, since it is not required. In many cases, the compiler could detect these issues. Detecting these would be a reasonable, if low priority, enhancement.

The problem if it detects it in an implementation-defined manner is the source code is no longer portable.

... If the result of compilation provably won't *run* anyway, what's the problem with a compile-time error?
Mar 01 2009
next sibling parent Christopher Wright <dhasenan gmail.com> writes:
Frits van Bommel wrote:
 Walter Bright wrote:
 Christopher Wright wrote:
 Walter Bright wrote:
 Christopher Wright wrote:
 Additionally, the compiler has sufficient information to complain 
 about the problem at compile time, but it doesn't. That is a bug.

No, it does not. The compiler doesn't know about private imports of separately compiled modules.

Okay, the compiler could gain that information, but it does not, since it is not required. In many cases, the compiler could detect these issues. Detecting these would be a reasonable, if low priority, enhancement.

The problem if it detects it in an implementation-defined manner is the source code is no longer portable.

... If the result of compilation provably won't *run* anyway, what's the problem with a compile-time error?

Right. It's like the compiler warning you if your program starts with "assert (false)".
Mar 01 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Frits van Bommel wrote:
 Walter Bright wrote:
 The problem if it detects it in an implementation-defined manner is 
 the source code is no longer portable.

... If the result of compilation provably won't *run* anyway, what's the problem with a compile-time error?

Nothing, it's just that the compiler cannot prove it is an error.
Mar 01 2009
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Walter Bright wrote:
 Frits van Bommel wrote:
 Walter Bright wrote:
 The problem if it detects it in an implementation-defined manner is 
 the source code is no longer portable.

... If the result of compilation provably won't *run* anyway, what's the problem with a compile-time error?

Nothing, it's just that the compiler cannot prove it is an error.

Not even on a best-effort basis? It doesn't have to catch every possible case; I for one would be perfectly fine with it if it didn't catch the "I omitted a private import from my .di file" case...
Mar 01 2009
parent Walter Bright <newshound1 digitalmars.com> writes:
Frits van Bommel wrote:
 Not even on a best-effort basis?
 It doesn't have to catch every possible case; I for one would be 
 perfectly fine with it if it didn't catch the "I omitted a private 
 import from my .di file" case...

Doing so would require full blown data flow analysis, which the front end is not equipped to do.
Mar 01 2009
prev sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Lutger wrote:
 grauzone wrote:
 
 Lars Ivar Igesund wrote:
 Eldar Insafutdinov wrote:

 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?


use this evil D feature? Yeah, that must it be. I can't explain why else these bugs/issues aren't fixed, and why people only reply with incredibly useful statements like "but you shouldn't use this feature anyway!". Broken features should be either fixed or removed. This half-assedness about it isn't really going to help D.

Well it's about cyclic dependency of initialization via module constructors only right? Cyclic imports in general aren't (supposed to be) broken, nor are module constructors.

And in point of fact, you can modify the runtime so it will not throw exceptions on cyclic dependencies: Index: genobj.d =================================================================== --- genobj.d (revision 4339) +++ genobj.d (working copy) -1098,11 +1098,7 if (m.ctor || m.dtor) { if (m.flags & MIctorstart) - { if (skip || m.flags & MIstandalone) - continue; - throw new Exception( "Cyclic dependency in module " ~ (from is null ? "*null*" : from.name) ~ " for import " ~ m.name); - } - + continue; m.flags |= MIctorstart; _moduleCtor2(m,m.importedModules, 0); if (m.ctor) This opens you up to certain bugs, but they should be relatively rare. I've tried it, and it appears to work.
Feb 28 2009
next sibling parent Fawzi Mohamed <fmohamed mac.com> writes:
On 2009-02-28 14:54:26 +0100, Christopher Wright <dhasenan gmail.com> said:

 Lutger wrote:
 grauzone wrote:
 
 Lars Ivar Igesund wrote:
 Eldar Insafutdinov wrote:
 
 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?


use this evil D feature? Yeah, that must it be. I can't explain why else these bugs/issues aren't fixed, and why people only reply with incredibly useful statements like "but you shouldn't use this feature anyway!". Broken features should be either fixed or removed. This half-assedness about it isn't really going to help D.

Well it's about cyclic dependency of initialization via module constructors only right? Cyclic imports in general aren't (supposed to be) broken, nor are module constructors.

And in point of fact, you can modify the runtime so it will not throw exceptions on cyclic dependencies: Index: genobj.d =================================================================== --- genobj.d (revision 4339) +++ genobj.d (working copy) -1098,11 +1098,7 if (m.ctor || m.dtor) { if (m.flags & MIctorstart) - { if (skip || m.flags & MIstandalone) - continue; - throw new Exception( "Cyclic dependency in module " ~ (from is null ? "*null*" : from.name) ~ " for import " ~ m.name); - } - + continue; m.flags |= MIctorstart; _moduleCtor2(m,m.importedModules, 0); if (m.ctor) This opens you up to certain bugs, but they should be relatively rare. I've tried it, and it appears to work.

Tango has it (thanks to lindquist) your change removes it :)
Feb 28 2009
prev sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Christopher Wright wrote:
 This opens you up to certain bugs,

Yes, the bug where module A depends on module B being initialized first, yet B imports A. With this patch, it may or may not work correctly, as order of initialization for cyclic imports will be unpredictable.
 but they should be relatively rare.

But nasty, as they tend to show up when porting or updating the compiler or build system, long after the original programmer left. Furthermore, these bugs may go undetected at QA time if nobody put a test for proper initialization in the test suite. Java is a very portable language, not because of the VM, but because it tries to eliminate all implementation and undefined behavior. It hasn't been 100% successful at that, but this facet of Java has, in my opinion, been a big factor in the wide adoption of Java. In contrast, only experienced C and C++ programmers are able to write code that ports reliably. Experience at having been burned by implementation and undefined language behavior. This is no longer acceptable in a language.
 I've tried it, and it appears to work.

That's the problem with undefined behavior :-(, it only appears to work. It is not guaranteed to work.
Feb 28 2009
prev sibling next sibling parent reply Eldar Insafutdinov <e.insafutdinov gmail.com> writes:
Lars Ivar Igesund Wrote:

 Eldar Insafutdinov wrote:
 
 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?

IMO it is the cyclic import that is the bug ;) -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango

I am not an expert but, Qt is a good example in my opinion, beause it is a mature API (fourth version) which shows that you can't go without cyclic dependencies in a very complex project.
Feb 28 2009
parent Lars Ivar Igesund <larsivar igesund.net> writes:
Eldar Insafutdinov wrote:

 Lars Ivar Igesund Wrote:
 
 Eldar Insafutdinov wrote:
 
 We faced a bug that module static constructors don't work with cyclic
 imports. Currently it's fixed with a dirty hack which is not really
 acceptable. Is there any chance for this to be fixed?

IMO it is the cyclic import that is the bug ;) -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango

I am not an expert but, Qt is a good example in my opinion, beause it is a mature API (fourth version) which shows that you can't go without cyclic dependencies in a very complex project.

I do not agree that this proves anything. My opinion is that a circular dependency at the very least is a hazardous design decision. In a class hierarchy this may work out well if there never ever will be any sub-classes to the involved classes, but typically this will come back and bite you in the toe when you cannot afford to redesign. I know D is less forgiving about this than other languages, and so it is a good help in creating a good design. Note that Java allows circular import dependencies, but not class dependencies at construction time (instance variables initialised prior to the constructor being run) which is similar to the static construction restriction in D. I understand that your issue is due to Qt's design and not your own, and as such the compiler could be more helpful, but in general I think the compiler should flag this at least at warning level (I agree with those who think it should be a compile time rather than a runtime error). -- Lars Ivar Igesund blog at http://larsivi.net DSource, #d.tango & #D: larsivi Dancing the Tango
Feb 28 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, Feb 28, 2009 at 3:05 PM, Walter Bright
<newshound1 digitalmars.com> wrote:
 Christopher Wright wrote:
 Additionally, the compiler has sufficient information to complain about
 the problem at compile time, but it doesn't. That is a bug.

No, it does not. The compiler doesn't know about private imports of separately compiled modules.

See it's funny, since in the other post, you said that using an autogenerated header file is semantically indistinguishable from compiling it to a metadata file. And here you're pointing out an obvious shortcoming!
Feb 28 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, Feb 28, 2009 at 5:30 PM, Derek Parnell <derek psych.ward> wrote:

 You can make hand-generated ones, too. The idea of keeping private
 imports private is to explicitly *avoid* dependencies on knowing the
 contents. It's a principle of encapsulization.

encapsuli...what? I definitedly need to conceptify that one :o).

I think the word Walter was reaching for was "encapsulement" =A0;-)

Encapsulosity.
Feb 28 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sat, Feb 28, 2009 at 11:05 AM, Yigal Chripun <yigal100 gmail.com> wrote:
 I agree with the above but there is still a small issue here:
 A module is a single file and when you have several large classes that are
 tightly coupled you can get a very big file with thousands of lines. what if
 i want to put each class in its own file?
 besides, the notion of a module is somewhat redundant - it's functionally a
 static struct.

 this is related to D's compilation model which is copied from C/C++ and it
 seems to me that this model is outdated. C#'s model of assemblies and
 metadata seems more capable. for instance there's no need for header files,
 that info is stored in the metadata of the assembly.

Preciiiisely. I've been toying with the concept of a compiler which doesn't actually emit object files until it has to link its code into some form of executable. Instead it produces these sort of platform-independent internal representation files, which can contain all the metadata and symbol information needed. They can be as small as a single module or as large as an entire multi-level package. It sounds a lot like the model C# has adopted.
Feb 28 2009