On Apr 26, 11 03:44, bearophile wrote:
Given that pre-conditions are meant to run fast and to be (nearly) pure, this
is my idea: when you call a function with all arguments known at compile time
(as at the r3 variable) the compiler runs just the pre-condition of that
function at compile-time (and not its body and post-condition).
The advantage is some bugs are caught at compile-time, and the compiler is kept
simple (I'd like contracts to be verified statically in more situations, but
this requires a more complex compiler). The disadvantage is longer compilation
times, and troubles caused by pre-conditions that can't really run at
compile-time (like a precondion that uses a compiler intrinsic). A way to solve
this last problem is to not raise an error if a pre-condition can't run at
compile-time, and just ignore it, and let it later run normally at run-time.
The variable r2 is a situation where not all arguments of foo() are known at
compile-time, so here the foo pre-condition is not run.
(Note: the variable r2 is a situation where one argument of foo is known at run-time, and in
this case the pre-condition contains a part (assert(x>=0&&x<text.length))
that's able to use this information to catch a bug. This is a possible improvement of the
idea is to perform this partial test. This looks less easy to implement, so it's not
important).
Bye,
bearophile
I feel this isn't right. The input or the precondition is very often not
compile-time evaluable, thus it just won't run. An example grabbed from
my code near by:
foreach (key; keys) // <-- keys is usually not known at
compile time
assert(key !in _map); // <-- 'in' is not CTFE-able (yet).
Also, if the precondition were complaining, and you change some bit of
the code and find it can be compiled -- that won't mean anything, as it
is likely the change just make the precondition non-CTFE-able. The
benefit doesn't worth the cost.
(And this is yet another kind of 0% false-positive-rate, non-zero
false-negative-rate feature. I bet you'll get a "false sense of
security" response. Personally I'd rather have the compiler to catch 50%
of compile-time detectable errors than leaving 100% of them to run time.)
I also don't believe this still keeps the compiler simple, as now there
are 2 kinds of CTFE error the compiler needs to distinguish: assert
errors and non-assert errors. I don't know much about the compiler
intrinsic, and actually the D front-end is already very complicated :),
so this doesn't matter.