December 16, 2011
On Dec 16, 2011, at 1:38 PM, Trass3r wrote:

> A related issue is phobos being an intermodule dependency monster. A simple hello world pulls in almost 30 modules!

This was one of the major motivations for separating druntime from phobos.  The last thing anyone wants is for something in runtime to print to the console and end up pulling in 80% of the standard library as a result.
December 16, 2011
On Dec 16, 2011, at 1:45 PM, Andrei Alexandrescu wrote:

> On 12/16/11 3:38 PM, Trass3r wrote:
>> A related issue is phobos being an intermodule dependency monster.
>> A simple hello world pulls in almost 30 modules!
>> And std.stdio is supposed to be just a simple wrapper around C FILE.
> 
> In fact it doesn't (after yesterday's commit). The std code in hello, world is a minuscule 3KB. The rest of 218KB is runtime.

Once upon a time, a minimal D app was roughly 65K.  TypeInfo has ballooned a lot since then however.  It's worth considering whether you're writing a Windows or Posix app as well, since the Posix headers are far more extensive (and thus may result in far more ModuleInfo instances).
December 16, 2011
On Dec 16, 2011, at 1:48 PM, Andrei Alexandrescu wrote:

> On 12/16/11 3:43 PM, Steven Schveighoffer wrote:
>> 
>> 
>> This can be solved with malloc and emplace
> 
> Sure you meant static ubyte[__traits(classInstanceSize, T)]
> and emplace :o).

Don't forget the 16 byte alignment :-)
December 16, 2011
On Dec 16, 2011, at 2:00 PM, Andrei Alexandrescu wrote:
> 
> I'm not an expert in linkers, but my understanding is that linkers naturally remove unused object files. That, coupled with dmd's ability to break compilation output in many pseudo-object files, would take care of the matter. Truth be told, once you link in Object.factory(), bam - all classes are linked.

There's an old bugzilla entry that may apply:

http://d.puremagic.com/issues/show_bug.cgi?id=879
December 16, 2011
On 12/16/11 4:39 PM, Jonathan M Davis wrote:
> It wouldn't be. It wouldn't need to be. The programmer is telling the compiler
> that there isn't a dependency. It's up to the programmer to make sure that
> it's right, and it's wrong, it's their fault. There are plenty of other
> features like that in D - just not SafeD.

I don't see progress here over arranging packages and modules to reflect program structure in a way that clarifies it to the human /and/ the compiler.

>>> annoying issues in D IMHO.
>> Adding a language construct that turns off the checking entirely (as you
>> seem to suggest) is not at all better than having to create a few
>> additional source files.
>
> I completely disagree. For instance, it's impossible to move the singleton
> instances of UTC and LocalTime from std.datetime into another module without
> breaking encapsulation, and it's definitely impossible to do it and leave them
> as members of their respective classes.

Maybe there's an issue with the design. Maybe Singleton (the most damned of all patterns) is not the best choice here. Or maybe the use of an inheritance hierarchy with a grand total of 4 classes. Or maybe the encapsulation could be rethought.

The general point is, a design lives within a language. Any language is going to disallow a few designs or make them unsuitable for particular situation. This is, again, multiplied by the context: it's the standard library.

> Those static constructors clearly
> don't rely on any other modules except for the one which gives the declaration
> for tzset (and has no static constructors). But if std.file needed a module
> constructor, we'd end up with a circular dependency between std.datetime and
> std.file when clearly nothing in std.datetime's static constructor relies on
> std.file in any way shape or form. It would be a huge improvement to be able to
> just mark those static constructors as not relying on any other modules having
> their static constructors run first. As it stands, it's a royal pain to deal
> with any circular dependencies which pop up and because of that, it quickly
> becomes best practice to avoid static constructors as much as possible, which
> is a big problem IMHO.

I think this point has gotten into an extreme, a corner of the design space. Yeah, sky's blue, apple pie is good (and too much of it gives diabetes), and module dependencies can be messy. But it strikes me as a bit backwards to add instructions in the core language to lessen guarantees and make things even messier, when alternatives exist that foster better dependency control for the very rare situations that need intervention. It's just not proportional response.

The persona using such a feature would be quite an odd combination - a developer with sophisticated enough needs to want unchecked dependencies as a feature, yet naive enough to be unable to solve the problem without the feature, and yet again sophisticated enough to not make mistakes in using said feature.

> Factoring out the static constructor's contents into a separate module is not
> always possible, and it's an ugly solution IMHO. I'd _much_ rather have a
> feature where I can tell the compiler that there is no circular dependency so
> that it can appropriately order the loading of the modules.

But what's the appropriate order then? :o)


Andrei
December 16, 2011
On 12/16/11 5:08 PM, Sean Kelly wrote:
> On Dec 16, 2011, at 1:38 PM, Trass3r wrote:
>
>> A related issue is phobos being an intermodule dependency monster.
>> A simple hello world pulls in almost 30 modules!
>
> This was one of the major motivations for separating druntime from
> phobos.  The last thing anyone wants is for something in runtime to
> print to the console and end up pulling in 80% of the standard
> library as a result.

Well, right now druntime itself may have become the interdependency knot it once wanted to shun :o).

Commenting out all static cdtors from druntime only reduced the code size from 218KB to 200KB for a do-nothing program, so most of druntime is compulsively linked and loaded. I think we can improve things a bit there.


Andrei
December 16, 2011
how did other languages solve this issue? I can't imagine D beeing the only language with static constructors, do they have that problem too?


December 16, 2011
On 12/17/2011 12:11 AM, Sean Kelly wrote:
> On Dec 16, 2011, at 1:48 PM, Andrei Alexandrescu wrote:
>
>> On 12/16/11 3:43 PM, Steven Schveighoffer wrote:
>>>
>>>
>>> This can be solved with malloc and emplace
>>
>> Sure you meant static ubyte[__traits(classInstanceSize, T)]
>> and emplace :o).
>
> Don't forget the 16 byte alignment :-)

Which is currently relatively easy:

http://d.puremagic.com/issues/show_bug.cgi?id=6635
December 16, 2011
On 12/16/2011 3:18 PM, maarten van damme wrote:
> how did other languages solve this issue? I can't imagine D beeing the only
> language with static constructors, do they have that problem too?

In C++, the order that static constructors run is implementation defined. No guarantees at all. The programmer has no reasonable way to control the order in which they are done.

(Of course, C++ doesn't even have modules, so the notion of a module constructor is tenuous at best.)
December 16, 2011
On 12/17/2011 12:18 AM, maarten van damme wrote:
> how did other languages solve this issue? I can't imagine D beeing the
> only language with static constructors, do they have that problem too?

Nobody has solved the issue. The approach in Java and C#, for instance, is to call the static constructor lazily upon class load time. That means it can be called at an arbitrary point during your program execution. And if you accidentally have circular dependencies between static constructors, your program may or may not blow up or behave badly.