March 10, 2010
Jacob Carlborg wrote:
> How dangerous would it be with a compiler option that allowed the above and the programmer have to make sure that they don't depend on each other?

The idea is to eliminate implementation-defined behavior as much as practical. I don't think it's at all easy for a programmer to look at a non-trivial static constructor and determine unequivocably that it does not depend on any imports.
March 10, 2010
Ellery Newcomer wrote:
> I hate the restriction on modules with static constructors and cyclic dependencies. IMO it's the most patronizing 'feature' D has. A year or so ago I ran into this issue during my first (and last) big project in D. Just last week I started working on it again and replaced everything that got initialized in a static constructor with stuff akin to
> 
> static Foobar foobar(){
>   static Foobar _foobar;
>   static bool inited = false;
>   if(!inited){
>     _foobar = new Foobar();
>     _foobar.init();
>     inited = true;
>   }
>   return _foobar;
> }

You could move the static ctor into another module outside of the cycle (e.g. the module where your main() function is). Then you get the same effects as "platform" dependent initialization.

It would be very practical if D has a "lose" version of the static ctor, that works even with cyclic dependencies. One could compare the module names or so to make the ordering deterministic across all linkers/platforms.

PS: I wonder why it's not considered a problem to execute unittests in random order? It's confusing if unittests fail "out of order", and the high level test fails first, even if the actual error is in some other low level module with its own unittests.
March 11, 2010
On 03/10/2010 01:10 PM, Walter Bright wrote:
> Ellery Newcomer wrote:
>> Maybe do a bit of analysis that can tell whether any static ctors in a
>> module use symbols from any other module and use that to determine
>> module dependencies?
>
> This is a transitive thing.

Hmm. That would make things obnoxious.

Furthermore, if you do anything nontrivial,
> you'll be referencing other module symbols. And finally, if you add some
> debugging code like a print statement, suddenly your code will no longer
> run.

Your code never ran in the first place otherwise. Or it did until you added some static constructors to initialize some field or other.


Just in case I didn't state my suggestion clearly (I think I did)

As I understand it, when a static constructor is found in a module A, then every imported module B must have its static constructor run prior to A's. So say you represent that as a flag associated with import B, or a directed edge in a graph, or whatever. If A has no static constructors then it doesn't participate in the ordering.

My suggestion is that when a symbol from import B is found in A's static constructor then B must be ordered before A, but otherwise not. I guess transitivity would require you to check the declaration of each local symbol that gets called in A's static constructor, or in general, everything in A. Come to think of it, that kind of information might be useful in the context of IDEs and 'find all usages of this symbol'. I might do this..

It wouldn't fix everything, but it would prune the number of dependencies that get castigated unjustly.

Don't think it's worthwhile? Maybe it isn't.
March 11, 2010
On 03/10/2010 05:14 PM, grauzone wrote:
>
> You could move the static ctor into another module outside of the cycle
> (e.g. the module where your main() function is). Then you get the same
> effects as "platform" dependent initialization.
>

most of my static ctors just set a logger object meant for use within the module. In retrospect, it was kind of a boneheaded thing to do, since the loggers all get initialized inside the logger module anyways.

Actually, all of it was to work around the idiom

static Object singleton = new Object();

which doesn't have a 1-1 correspondence in D. I've converted most of them to enums..

March 11, 2010
Ellery Newcomer wrote:
> I guess transitivity would require you to check the declaration of each local symbol that gets called in A's static constructor,

Everything referenced by everything referenced, etc., in the constructor, all the way.

It's not even possible to do in full generality, because the D compiler won't have the source to everything.
March 11, 2010
On Wed, 10 Mar 2010, Walter Bright wrote:

> Ellery Newcomer wrote:
> > I guess transitivity would require you to check the declaration of each local symbol that gets called in A's static constructor,
> 
> Everything referenced by everything referenced, etc., in the constructor, all the way.
> 
> It's not even possible to do in full generality, because the D compiler won't have the source to everything.

In the D spirit of things, ie, stay conservative:

If you can prove that the closure of code that the static constructor touches doesn't escape the file, which you can do fairly easily and you can guarantee that you've got all the code for that check, then the ctor could be flagged as self-contained and take itself out of the running for loop detection.

Later, potentially more aggressive logic could be written, time and/or volunteers permitting.

Later,
Brad
March 11, 2010
Brad Roberts wrote:
> In the D spirit of things, ie, stay conservative:
> 
> If you can prove that the closure of code that the static constructor touches doesn't escape the file, which you can do fairly easily and you can guarantee that you've got all the code for that check, then the ctor could be flagged as self-contained and take itself out of the running for loop detection.
> 
> Later, potentially more aggressive logic could be written, time and/or volunteers permitting.

There is a problem with that - the error message about circular dependencies will come and go in a fairly erratic manner (at least from the user's perspective).
March 11, 2010
On 3/10/10 22:59, Justin Johansson wrote:
> Jacob Carlborg Wrote:
>
>> On 3/10/10 16:33, Steve Teale wrote:
>>>>
>>>> The #1 show-stopper for me was lack of shared object (.so) support under
>>>> Linux; virtually mandated by my audience (Apache/LAMP).  (A workaround
>>>> like FastCGI is simply not appealing to customers.)  This topic
>>>> discussed many times before on this NG.
>>>>
>>>>
>>> I also had done a fair amount of work, and foundered on the inability to
>>> dynamically load anything without it being a big deal.
>>>
>>> Like you say, it has been brought up many many times. Everyone says yes,
>>> this is a real show-stopper, then the thread dies down and so on.
>>>
>>> Steve
>>
>> What are the exact problems that people have with shared libraries on
>> linux? I've made a few dynamic libraries on Mac OS X of which only one
>> didn't work (I have no idea why). Among the working libraries were DWT
>> and Tango.
>
> DMD on Linux does not support the creation of shared libraries.

Is that the runtime or the compiler? What about GDC, too old?

March 11, 2010
On 3/10/10 23:50, Walter Bright wrote:
> Jacob Carlborg wrote:
>> How dangerous would it be with a compiler option that allowed the
>> above and the programmer have to make sure that they don't depend on
>> each other?
>
> The idea is to eliminate implementation-defined behavior as much as
> practical. I don't think it's at all easy for a programmer to look at a
> non-trivial static constructor and determine unequivocably that it does
> not depend on any imports.

The reason I suggested to add a compiler switch is because I usually have very simple static constructors.
March 11, 2010
Jacob Carlborg Wrote:

> On 3/10/10 22:59, Justin Johansson wrote:
> > Jacob Carlborg Wrote:
> >
> >> On 3/10/10 16:33, Steve Teale wrote:
> >>>>
> >>>> The #1 show-stopper for me was lack of shared object (.so) support under
> >>>> Linux; virtually mandated by my audience (Apache/LAMP).  (A workaround
> >>>> like FastCGI is simply not appealing to customers.)  This topic
> >>>> discussed many times before on this NG.
> >>>>
> >>>>
> >>> I also had done a fair amount of work, and foundered on the inability to dynamically load anything without it being a big deal.
> >>>
> >>> Like you say, it has been brought up many many times. Everyone says yes, this is a real show-stopper, then the thread dies down and so on.
> >>>
> >>> Steve
> >>
> >> What are the exact problems that people have with shared libraries on linux? I've made a few dynamic libraries on Mac OS X of which only one didn't work (I have no idea why). Among the working libraries were DWT and Tango.
> >
> > DMD on Linux does not support the creation of shared libraries.
> 
> Is that the runtime or the compiler? What about GDC, too old?

AFAIK, it is the linker; something about Linux/Unix ELF object file formats perhaps .. though I'm out of my depth now.  Maybe others can explain better.

I've never used GDC so cannot say what the issues might be there.

Think this thread needs a new subject line to raise the visibility of the issue.  Granted though that Walter has acknowledged the issue (at long last).

Understandably Walter has lots on his plate; what can be done to help out?

Cheers, Justin