November 29, 2012
On Thursday, 29 November 2012 at 02:34:11 UTC, Walter Bright wrote:
> 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.

It is natural. It just doesn't cover important use cases.

>
> 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.

Can we have that implemented in a branch and see how it goes?
November 29, 2012
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?

>
> 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




November 29, 2012
On Thursday, November 29, 2012 12:39:19 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.
> 
> 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.

Basic features in the language require static constructors (e.g. static variables frequently do), and some things just can't be done without them. Andrei's std.benchmark proposal actually doesn't work, because in order to do what it does, in needs to mixin in a static constructor and static destructor (to set up the benchmarking and record it at the end, I believe). That completely falls apart due to cyclical imports. It doesn't actually cause any true circular dependencies, but it's treated as such anyway. A _lot_ of us have run into this problem and a number of us consider it to be a huge design problem in the language. Personally, I'd put it towards the top of design mistakes at this point, and I'm very glad to see Walter actually finally being willing to do something about this. In the past when I've brought up similar solutions, he's been completely opposed to them.

Yes, we have other major issues that need to be resolved, and those may very well be of a higher priority, but this is still a very import issue, and it's the sort of issue that can probably be implemented with minimal effort. The main thing is getting Walter to agree to it and how it will be done. Once a decision is made, it wouldn't surprise me if someone like Kenji were able to get it done very quickly.

- Jonathan M Davis
November 29, 2012
Walter Bright wrote:

> It means that [...] the static constructor for this
> module may be run before

This is sufficient only for a simple cycle without any branches or a trivial clique like the one shown. Please recall, that in a clique every member is connected to every other member---in this case by an import statement.

It is already not sufficient for a simple clique consisting of three modules, because now orderinh would be given for the remaining two modules.

And it is ambiguous if both of the modules in the example given are marked with that pragma.

In general a topological sorting has to be specified for all strongly connected components of the graph of imports.

This cannot be done within the module, because this would bind the module to that special strongly connected component in that special set of  modules. Which in turn would destroy reusability of the module for other programming tasks.

Therefore: marking with a pragma isn't a fix for the depicted problem.

-manfred




November 29, 2012
"Walter Bright" <newshound2@digitalmars.com> wrote in message news:k96hj2$2lus$1@digitalmars.com...
> For discussion:
>
> Cyclical Imports
>
> Problem:
>
>
> 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.
>

I don't think this is sufficient.  Imagine a group of modules that really _do_ have a cyclic dependency, and a mixin that adds an independent static this.  Ideally you'd be able to mark the mixed-in constructor as independent without tainting the whole module.

So just make the pragma apply to declarations, you either mark specific functions (which can then be mixed in) or put `pragma(...):` at the top of your module and you get your behaviour.


November 29, 2012
On 11/28/12 10:34 PM, Adam D. Ruppe wrote:
> 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....

On the other hand if we work on every easy and unimportant fix we miss big on the important stuff.

http://c2.com/cgi/wiki?FourQuadrants


Andrei
November 29, 2012
On 11/28/12 11:26 PM, bearophile wrote:
> 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?

Construction flow and copy conversion.

Andrei

November 29, 2012
On 11/29/12 12:07 AM, bearophile wrote:
>> what's left to do for const and immutable?
>
> I guess the answer is too much long, so please ignore the question.

Ars longa vita brevis est.

Andrei
November 29, 2012
On 11/29/12 12:25 AM, Jonathan M Davis wrote:
> 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.

My perception is that we need to tackle the major issues at this point: process and qualifiers (including shared).

> 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.

Enhancement requests are the right place for those. Now that we have forum.dlang.org we can link to discussions, too.


Andrei

November 29, 2012
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?

--
Paulo