November 29, 2012
For discussion:

Cyclical Imports

Problem:

---- a.d ----
    module a;
    import b;
    static this () { ... }
---- b.d ----
    module b;
    import a;
    static this() { ... }
-------------

Static constructors for a module are only run after static constructors
for all its imports are run. Circular imports, such as the above, are
detected at run time and the program is aborted.

This can in general be solved by moving the static constructor(s) into
a third module, c.d, which does not import a or b. But, people find this
to be unnatural.

Proposed Solution:

Add a pragma,

    pragma(cyclic_imports);

This can appear anywhere in a module, and applies globally to that module.
It means that static constructors from imports that are not part of the cycle
are run first, and that the static constructor for this module may be run before
the static constructors of other modules that are part of the cycle.

If any static constructors in such a module with the pragma have
the @safe attribute, that is a compile time error.
November 29, 2012
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
November 29, 2012
On Thursday, 29 November 2012 at 03:19:55 UTC, Andrei Alexandrescu wrote:
> I'd say we better finish const, immutable, and shared first.

If we put off every easy fix until all the hard fixes are done, it means we have longer wait times on everything....
November 29, 2012
Andrei Alexandrescu:

> I'd say we better finish const, immutable, and shared first.

There are few things left to implement for purity (they are listed in Bugzilla), but what's left to do for const and immutable?

Bye,
bearophile
November 29, 2012
> what's left to do for const and immutable?

I guess the answer is too much long, so please ignore the question.

Bye,
bearophile
November 29, 2012
On Wednesday, November 28, 2012 22:19:54 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.

Both problems need to be addressed, and this one is probably easier. It also has a huge impact on std.benchmark, so I would have thought that you'd be more in favor of it.

However, we do have a tendancy to bring up problems like this, discuss them for a while, and then let them be more or less forgotten for a while. It keeps happening with stuff like const ref / auto ref, shared, const and Object, const postblit constructors, @trusted blocks, etc. And we need to actually get them sorted out.

- Jonathan M Davis
November 29, 2012
On 11/29/12 03:34, Walter Bright wrote:
> Proposed Solution:
> 
> Add a pragma,
> 
>     pragma(cyclic_imports);
> 
> This can appear anywhere in a module, and applies globally to that module.
> It means that static constructors from imports that are not part of the cycle
> are run first, and that the static constructor for this module may be run before
> the static constructors of other modules that are part of the cycle.

Bad name. Something like "module_ctors_unordered" would be better (I don't like that one either, but this way it's at least clear what it does).

The equivalent attribute version could be

   module mymodule @unordered_ctors;

which is better, but still has the problem that adding another module ctor can result is silent breakage. These things can be mixed in, so something as innocent looking as

   import some_lib;
   [...]
   mixin blah;

can already be a bug. Hence:

   static this() @unordered { /*whatever*/ }

and then either enforce that all mod-ctors have this attribute (otherwise every ctor in that moduile gets treated as ordered), or split them into two sets (better, but larger change; backward compatible, just requires a new enough runtime to be used).

Of course it could be also done as

    static this() pragma(unordered) { /*whatever*/ }

but this wouldn't really be better, and would require language change (the fact that you cannot attach a pragma to /anything/ is already a problem, eg for gcc-specific attributes).

"@unordered" could even be inferred, but I'm not sure how often that would help in practice. At least w/o making module-level imports invisible inside module ctors (which would make the deps explicit).

artur
November 29, 2012
On Thursday, November 29, 2012 07:36:41 Artur Skawina wrote:
> On 11/29/12 03:34, Walter Bright wrote:
> > Proposed Solution:
> > 
> > Add a pragma,
> > 
> >     pragma(cyclic_imports);
> > 
> > This can appear anywhere in a module, and applies globally to that module. It means that static constructors from imports that are not part of the cycle are run first, and that the static constructor for this module may be run before the static constructors of other modules that are part of the cycle.
> Bad name. Something like "module_ctors_unordered" would be better (I don't like that one either, but this way it's at least clear what it does).

no_cyclic_imports would probably be better given that you're trying to get around a cyclic import, but I don't see what's unclear about cyclic_imports given that that's exactly what the runtime complains about when this problem occurs.

> but still has the problem that adding another module ctor can result is silent breakage.

That's actually a really good argument IMHO for having to put the pragma or attribute on every single static constructor in a module. True, it may be a bit annoying, but it would avoid silent breakage.

- Jonathan M Davis
November 29, 2012
On 2012-11-29 03:34, Walter Bright wrote:

> Add a pragma,
>
>      pragma(cyclic_imports);
>
> This can appear anywhere in a module, and applies globally to that module.
> It means that static constructors from imports that are not part of the
> cycle
> are run first, and that the static constructor for this module may be
> run before
> the static constructors of other modules that are part of the cycle.

I would think that "cyclic_imports" sounds like the static constructors are part of the cycle.

-- 
/Jacob Carlborg
November 29, 2012
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.

Turbo Pascal/Delphi is the only language that I know fully allows cyclic dependencies between modules. So this is not that important for most people.

--
Paulo
« First   ‹ Prev
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home