February 28, 2009
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.
February 28, 2009
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.

February 28, 2009
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?
>>> 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.

Additionally, the compiler has sufficient information to complain about the problem at compile time, but it doesn't. That is a bug.
February 28, 2009
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?
>>> 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.
> 

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.
February 28, 2009
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

February 28, 2009
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.
February 28, 2009
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.
February 28, 2009
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!
February 28, 2009
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.
February 28, 2009
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