November 29, 2012 Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | 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 Re: Fixing cyclic import static construction problems | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | 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
|
Copyright © 1999-2021 by the D Language Foundation