On Thursday, November 29, 2012 16:18:10 Paulo Pinto wrote: > On Thursday, 29 November 2012 at 12:04:28 UTC, Max Samukha wrote: > > On Thursday, 29 November 2012 at 11:39:20 UTC, Paulo Pinto > > > > wrote: > >> On Thursday, 29 November 2012 at 03:19:55 UTC, Andrei > >> > >> Alexandrescu wrote: > >>> On 11/28/12 9:34 PM, Walter Bright wrote: > >>>> For discussion: > >>> [snip] > >>> > >>> I'd say we better finish const, immutable, and shared first. > >>> > >>> Andrei > >> > >> +1 > >> > >> Fully agree. > >> > >> Cyclic imports are a minor nuisance that can be easily > >> solvable with better code architecture. > > > > Show me please how to solve that problem easily with acceptable > > results, would you? > > You just need to have a better architecture. > > In 20 years of software development experience I never found a > case were this wasn't possible. > > Maybe you care to provide an example?
Considering that you need static constructors to initialize any static variables at runtime (and in the case of const and immutable variables, you _can't_ work around that by doing the initialization later - it _must_ be in the static constructor), and all it takes for the compiler to declare a circular import is to have two modules import each other - even indirectly - it becomes extremely easy to run into this problem. And if you're dealing with immutable static variables which are initialized at runtime, you can't fix it unless you can contort your modules so that they don't depend on each other, and with a lot of modules, that can become extremely difficult. We had to strip out all static constructors from std.datetime because of this, and in order to fix it, we had to do some nasty voodoo with casting in order to lazily initialize some variables which are supposed to be immutable. _None_ of that sort of thing should be necessary. As it stands, it's basically bad practice to use static constructors, because it's so easy to end up with circular dependencies, and they can involve modules which don't seem even vaguely related because of other stuff that they import and are often a royal pain to debug and fix, if you even can without seriously revamping your design. And for a library like Phobos which needs to avoid breaking backwards compatibility, redesigning things to avoid such circular dependencies isn't necessarily even possible, because those redesigns would break backwards compatibliity. We _need_ a solution for this. Whether now is the best time tackle it is another matter, but the current situation with static constructors is ridiculous. There are features which require them, but you have to avoid them or you're going to run into circular dependency issues very easily. This is a case of some great design decisions in D have leading to a very bad design, and it needs to be fixed. Fortunately, it shouldn't be all that hard to fix with an attribute of some kind. But prior to now, Walter wouldn't even consider it. I do think though that the idea of using only one pragma instead of an attribute/pragma per static constructor is a bad idea because of the silent breakage that it would cause, as has been pointed out in this thread. So, his proposed solution needs some tweaking. - Jonathan M Davis
