Program size, linking matter, and static this()

Jonathan M Davis jmdavisProg at gmx.com
Fri Dec 16 15:50:51 PST 2011


On Friday, December 16, 2011 17:13:49 Andrei Alexandrescu wrote:
> 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.

I don't know what's wrong with singletons. It's a great pattern in certain 
circumstances. In this case, it avoids unnecessary allocations every time that 
you do something like Clock.currTime(). There's no reason to keep allocating 
new instances of LocalTime and wasting memory. The data in all of them would 
be identical. And since the time zone has to be dynamic, it requires either a 
class or function pointers (or delegates). And since multiple functions are 
involved per time zone, it's far cleaner to use class. It has the added 
benefit of giving you a nice place to do stuff like ask the time zone its name. 
So, I don't see what could be better than using classes for the time zones 
like it does now. And given the fact that it's completely unnecessary and 
wasteful to allocate multiple instances of UTC and LocalTime, it seems to me 
that the singleton pattern is exactly the correct solution for this problem.

There would be fewer potential issues with circular dependencies if 
std.datetime were broken up, but the consensus seems to be that we don't want 
to do that. Regardless, if I find a way to lazily load the singletons in spite 
of immutable and pure, then there won't be any more need for the static 
constructors for them. There's still one for the unit tests, but worse comes 
to worst, that functionality could be moved to a function which is called by 
the first unittest block.

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

It doesn't matter. The static constructors in std.datetime has no dependencies 
on other modules at all aside from object and the core module which holds the 
declaration for tzset. In neither case does it depend on any other static 
constructors. In my experience, that's almost always the case. But because of 
how circular dependencies are treated, the compiler/runtime considers it a 
circular dependency as soon as two modules which import each other directly - 
or worse, indirectly - both have module constructors, regardless of whether 
there is anything even vaguely interdependent about those static constructors 
and what they initialize. So, you're forced to move stuff into other modules, 
and in some cases (such as when pure or immutable is being used), that may not 
work.

Clearly, I'm not going to win any arguments on this, given that both you and 
Walter are definitely opposed, but I definitely think that the current situation 
with circular dependencies is one of D's major warts.

- Jonathan M Davis


More information about the Digitalmars-d mailing list