I was distracted and with a unfocused mind, sorry for the late reply.

Walter:

> We thought about this approach and deliberately did not do it.

Thank you for your answer. Sometimes it doesn't harm to think again a bit about 
a topic.


> It is not predictable at compile time whether a function can be executed
> at compile time or not (the halting problem). Therefore, you'll wind up
> with cases that silently fail at compile time, and so are put off until
> runtime. The user cannot tell (without looking at assembly dumps) if it
> happened at compile time or not.
> 
> Instead, we opted for a design that either must run at compile time, or
> must run at run time. Not one that decides one way or the other in an
> arbitrary, silent, and ever-changing manner.

In this discussion I was talking about running just the pre-conditions, and not 
the whole function, and not its post-condition.

This is different because:
- Pre-conditions are usually small or smaller than function bodies;
- Pre-conditions are usually meant to be fast (and not slower than the function 
body), so they are probably not too much heavy to run. pre-conditions, unlike 
debug{} code are meant to run often;
- Pre-conditions are often pure (mine). If the "feature" I am talking about 
gets introduced, D programmers will be encouraged to write more pure 
preconditions (this probably explains why most other Contract-based systems 
I've seen don't use free code in contracts as D does, but use a specific 
expression language. This forces them to be pure and simpler, more fit for 
analysis!). Even if a function is not marked as "pure", what matters in this 
discussion is to its pre-condition to be CTFE-pure.

The problem you list is of course important for the normally run CT functions, 
and I agree with the decision. But it's much less important for my idea, 
because I've seen that finding bug in code is essentially never a deterministic 
process, it's very probabilistic. People find only some bugs (people today find 
new bugs even in 10+ years old very-high-quality C code used by everyone 
(Zlib)), lint tools (including the static analysis flag of Clang I've shown 
recently) find only some other bugs, and different lints find different bugs. 
One important factor for those tools is to reduce false positives as much as 
possible (even if this increases false negatives a little), and this idea of 
mine produced zero false alarms (if the pre-conditions are written correctly).

This feature is useful because when in your code you have struct literals like:

Foo f1 = Foo(10, -20);

The compiler is able at compile-time to tell you that line of code is wrong 
because -20 is not acceptable :-) This is useful in many situations. This 
feature works only if the arguments are known at compile-time, this is a strong 
limitation, but I think it's better to have it anyway.

Even if this feature sometimes gets disabled by turning a CTFE-pure function 
pre-condition into not CTFE-pure code as you say, the programmer doesn't need 
to care a lot about this, because even if this change doesn't allow to catch a 
bug in the code, other bugs too are not found by the compiler. All static 
analysis tools do the same, they sometimes find a bug, but if you change the 
code in a way they don't fully understand, they don't find the bug any more. 
This is why I think your argument doesn't hold.

The feature I have proposed is not a language feature, it's a compiler feature 
(the only change is in user code, that's encouraged to create CTFE-pure 
pre-conditions). This means that even if DMD doesn't want this idea, future D 
compilers will be free to adopt it. And from the direction of the tide (as 
Clang adds better and better analysis for C and C++ code) I think this will be 
seen as a cheap but useful compiler feature to add (a "low-hanging fruit" 
because the only needed compiler change I see needed is to not stop the 
compilation if a pre-condition of a function with statically known arguments 
turns out to be not runnable).

Bye,
bearophile

Reply via email to