Program size, linking matter, and static this()
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Fri Dec 16 12:44:48 PST 2011
On 12/16/11 1:41 PM, Jonathan M Davis wrote:
> You could make core.time use property functions instead of the static
> immutable variables that it's using now for ticksPerSec and
> appOrigin, but in order to do that right would require introducing a
> mutex or synchronized block (which is really just a mutex under the
> hood anyway), and I'm loathe to do that in time-related code.
> ticksPerSec gets used all over the place in TickDuration, and that
> could have a negative impact on performance for something that needs
> to be really fast (since it's used in stuff like StopWatch and
> benchmarking). On top of that, in order to maintain the current
> semantics, the property functions would have to be pure, which they
> can't be without doing some nasty casting to convince the compiler
> that stuff which isn't pure is actually pure.
>
> For std.datetime, the problem would be reduced if a class could be
> created in CTFE and still be around at runtime, but we can't do that
> yet, and it wouldn't completely solve the problem, since the shared
> static constructor related to LocalTime has to call tzset. So, some
> sort of runtime initialization must be done. And the instances for
> the singleton are not only immutable, but the functions for getting
> them are pure. So, once again, some nasty casting would be required
> to get it to work without breaking purity. And once again, we'd have
> introduce a mutex. And for both core.time and std.datetime we're
> talking about a mutex would be needed only briefly to ensure that we
> don't end up with two threads trying to initialize the variable at
> the same time. After that, it would just be impeding performance for
> no value. They're classic situations for static constructors -
> initializing static immutable variables - and really, they _should_
> be using static constructors. If we have to get rid of them, it's to
> get around other problems in the language or compiler instead of
> fixing those problems. So, on some level, that seems like a failure
> on the part of the language and the compiler. If we _have_ to find a
> workaround, then we have to find a workaround, but I find the need to
> be distasteful to say the least. I previously tried to get rid of the
> static constructors in std.datetime and couldn't precisely because
> they're needed unless you play major casting games to get around
> immutable and pure.
>
> If we play nice, it's impossible to get rid of the static
> constructors in std.datetime. It probably is possible if we do nasty
> casting, but (much as I hate to use the word) it seems like this is a
> hack to get around the fact that the compiler isn't dealing with
> static constructors as well as we'd like. I'd _really_ like to see
> this fixed at the compiler level.
I understand and empathize with the sentiment, and I agree with most of
the technical points at face value, save for a few details. But there
are other things at stake.
Consider scope. Many arguments applicable to application code are not
quite fit for the standard library. The stdlib is the connection between
the compiler innards, the runtime innards, and the OS innards all meet,
and the role of the stdlib is to provide nice abstractions to client
code. Inside the stdlib it's entirely expected to find things like
__traits most nobody heard of, casts, and other things that would be
normally shunned in application code. I'd be more worried if there was
no possibility to do what we need to do. The standard library is not a
place to play it nice. We can't afford to say "well yeah everyone's
binary is bloated and slower to start but we didn't like the cast that
would have taken care of that".
As another matter, there is value in minimizing compulsive work during
library startup. Consider for example this code in std.datetime:
shared static this()
{
tzset();
_localTime = new immutable(LocalTime)();
}
This summons the garbage collector right off the bat, thus wiping off
anyone's chance of compiling and linking without a GC - as many people
seem to want to do. And that happens not to programs that import and use
std.datetime, but to program using any part of the standard library that
transitively imports std.datetime, even for the most innocuous uses, and
even if they never, ever use _localtime! That one line essentially locks
out 75% of the standard library to anyone wishing to ever avoid using
the GC.
> And honestly, I think that a far worse problem with static
> constructors is circular dependencies. _That_ is something that
> needs to be addressed with regards to static constructors. In general
> at this point, it's looking like static constructors are turning out
> to be a bit of a failure on some level, given the issues that we're
> having because of them, and I think that we should fix the language
> and/or compiler so that they _aren't_ a failure.
Here I totally disagree. The design is sound. The issues discussed here
are entirely detail implementation artifacts.
Andrei
More information about the Digitalmars-d
mailing list