www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal: static ctor priority

reply Daniel Keep <daniel.keep.lists gmail.com> writes:
The other night, I was writing code for a game prototype when I ran into
the old cyclic module dependency problem.

Basically, the issue was that engine imports window, and window needs to
talk to the engine.  Both have loggers for writing out debug
information, which are (ideally) created in static ctors.

So, even though there is no *actual* dependency between the ctors, they
still fail to compile.  Previously, people have suggested flow analysis
to solve this, but flow analysis would be a lot of work.

Therefore, my proposal is to introduce a new pragma to resolve this.
Example:

module a;
import b;

pragma(priority, 2)
static this()
{
    // Do stuff
}

module b;
import a;

// defaults to priority 1.
static this()
{
    // Do other stuff
}

(NB: modules are initialised from higher priority (int.max) to lowest
(int.min))

This would allow developers to manually break these cycles by specifying
 the relative order they should be initialised in.  For bonus points,
make this possible:

module a;
import b;

pragma(priority, b+1)
static this() {
...

This should be much easier to implement than flow analysis, whilst still
solving the problem.

Comments?

	-- Daniel
Jun 20 2007
next sibling parent Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
Daniel Keep wrote:
 Example:
 
 module a;
 import b;
 
 pragma(priority, 2)
 static this()
 {
     // Do stuff
 }
 
 module b;
 import a;
 
 // defaults to priority 1.
 static this()
 {
     // Do other stuff
 }
 
 (NB: modules are initialised from higher priority (int.max) to lowest
 (int.min))
 
 This would allow developers to manually break these cycles by specifying
  the relative order they should be initialised in.  For bonus points,
 make this possible:
 
 module a;
 import b;
 
 pragma(priority, b+1)
 static this() {
 ...
 
 This should be much easier to implement than flow analysis, whilst still
 solving the problem.
 
 Comments?

We already have the parentheses after "static this", why not reuse them? We don't need a pragma: static this(1) { ... } static this(2) { called before the above... } static this() { called whenever... } If we'll ever get more than one module constructor per module (I hope we will), "b+1" priority would have to mean "max(all in b) + 1". Not a problem, just making a note. -- Remove ".doesnotlike.spam" from the mail address.
Jun 21 2007
prev sibling next sibling parent BCS <ao pathlink.com> writes:
Reply to Daniel,

 The other night, I was writing code for a game prototype when I ran
 into the old cyclic module dependency problem.
 
 Basically, the issue was that engine imports window, and window needs
 to talk to the engine.  Both have loggers for writing out debug
 information, which are (ideally) created in static ctors.
 
 So, even though there is no *actual* dependency between the ctors,
 they still fail to compile.  Previously, people have suggested flow
 analysis to solve this, but flow analysis would be a lot of work.
 
 Therefore, my proposal is to introduce a new pragma to resolve this.
 Example:
 
 module a;
 import b;
 pragma(priority, 2)
 static this()
 {
 // Do stuff
 }
 module b;
 import a;
 // defaults to priority 1.
 static this()
 {
 // Do other stuff
 }
 (NB: modules are initialised from higher priority (int.max) to lowest
 (int.min))
 
 This would allow developers to manually break these cycles by
 specifying
 the relative order they should be initialised in.  For bonus points,
 make this possible:
 module a;
 import b;
 pragma(priority, b+1)
 static this() {
 ...
 This should be much easier to implement than flow analysis, whilst
 still solving the problem.
 
 Comments?
 
 -- Daniel
 

I'd reather it be done with explicet flow ordering module foo; import bar, baz; this(baz){writef("foo\n");} module bar; import foo, baz; this(foo, baz){writef("bar\n");} module baz; import foo, ; this(null){writef("baz\n");} output: baz foo bar Any cycle are explicit errors (at compile time if it can be detected then), "null" means no dependencies, "()" means everything imported and a list means only that list. Actually I'd rather it be even more flexible than that but I can't think of a clean way to code what I want.
Jun 21 2007
prev sibling parent "Kristian Kilpi" <kjkilpi gmail.com> writes:
Something like this is needed. I wouldn't mind doing some manual tweaking  
to get the things compile.
(The actual syntax is not so important for me.)


On Thu, 21 Jun 2007 08:57:32 +0300, Daniel Keep  
<daniel.keep.lists gmail.com> wrote:
 The other night, I was writing code for a game prototype when I ran into
 the old cyclic module dependency problem.

 Basically, the issue was that engine imports window, and window needs to
 talk to the engine.  Both have loggers for writing out debug
 information, which are (ideally) created in static ctors.

 So, even though there is no *actual* dependency between the ctors, they
 still fail to compile.  Previously, people have suggested flow analysis
 to solve this, but flow analysis would be a lot of work.

 Therefore, my proposal is to introduce a new pragma to resolve this.
 Example:

 module a;
 import b;

 pragma(priority, 2)
 static this()
 {
     // Do stuff
 }

 module b;
 import a;

 // defaults to priority 1.
 static this()
 {
     // Do other stuff
 }

 (NB: modules are initialised from higher priority (int.max) to lowest
 (int.min))

 This would allow developers to manually break these cycles by specifying
  the relative order they should be initialised in.  For bonus points,
 make this possible:

 module a;
 import b;

 pragma(priority, b+1)
 static this() {
 ...

 This should be much easier to implement than flow analysis, whilst still
 solving the problem.

 Comments?

 	-- Daniel

Jun 22 2007