Reducing the inter-dependencies (in Phobos and at large)

Dmitry Olshansky dmitry.olsh at gmail.com
Wed Apr 24 12:33:46 PDT 2013


24-Apr-2013 20:08, qznc пишет:
> On Wednesday, 24 April 2013 at 12:03:52 UTC, Dmitry Olshansky wrote:
>> Basically an import graph of Phobos is a rat's nest of mutual imports.
>> With the most of modules being template "toolkits" you shouldn't pay
>> for what you don't use. Yet it isn't true in general as the module may
>> drag in other modules and with that all of static constructors and/or
>> globals related.
>> Thoughts? Other ideas?
>
> I think your concept idea introduces unnecessary complexity.

It reduces the complexity of full module imports and helps avoid 
circular dependencies. Problem is that compiler can't know that all you 
need that module for is a few isolated templates.

If compiler sees this:

module abc;

import xyz;

That means that
a) abc depends xyz and thus all of the  global state in xyz if there are 
any. Cue to the idea that globals are bad - you can't easily track the 
usage of them esp. with separate compilation model.

b) if xyz happen to use stuff from abc compiler has to "turn on" cross 
module dependency checks and define the order of ctor/dtor evaluation.
More importantly in current setting is the fact that it's not good at it 
and conservative (as it may as well stay forever).

c) It may be the case that both modules define ctors and then you have 
genuine circular dependency.

d) Another (bogus) case is that it may as throw up hands in the air and 
spit a bunch of forward reference bugs.

Arguably it could be framed as poor modularity in the Phobos design.
A specific problem with templates is that in order to get a "duck type" 
you pull the whole innards of module.

That's why I see that duck types could and should be peeled off from 
modules.

> What are you actually worried about? Compile times? Program size?
> Startup time?

It affects all of it.

First and furthermost unnecessary and unavoidable junk that resides in 
your program. Unnecessary "fake" dependencies on stuff your module 
doesn't need.  In the end with current setting a single touch of say 
std.file pulls in a measurable amount of stuff (including ctors/dtors 
that are run at startup/shutdown) you never wanted.

>
> Is compile time a problem?

For libraries modularity and minimal dependencies are corner stones of 
good design. I'd throw among these flexibility and pay and as go 
principle as other key concerns.

The fact that D compiles fast can always be undermined by the way we 
structure the code and dependencies.

> Program size should be handled by the compiler. It is much better at
> pruning dead code.

In case it know the code is dead. Throwing bunch of stuff at it that is 
actually interdependent (the way it's written) doesn't help. The fact 
that a lot of it is truly independent bears no relation to it partially 
because of the compilation model.

>
> Startup time should be handled by the modules themselves. For example,
> std.random could initialize the global RNG only on demand.

Doesn't help to have gobla data for it. Not to say that the said dead 
code for lazy initialization would pulled in always. And the other guy 
that needs global PRGN now has to go through a "is-it-inited-yet" hook 
_always_. You suggestion is a net loose on both counts then.

To summarize your point - you don't care and/or don't see it as a 
problem. That's fine but and it then it just doesn't affect you in any way.
For Phobos developers to work a bit harder to design a cleaner 
dependency chain so that you code loads less junk is a net gain.
All of that should concern Phobos guys and library writers.

Another question - did you ever read C run-time sources? They are 
carefully modularized "by hand" so that if you want say printf you get 
only what you truly need for it.

We currently do a very bad job at this kind of thing and it's not 
entirely the compiler's fault.


-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list