Idea: function contracts + CTFE

Yigal Chripun yigal100 at gmail.com
Fri Jun 20 13:50:37 PDT 2008


Jarrett Billingsley wrote:
> I've found myself not using contracts nearly as much as I'd kind of like to. 
> Mostly because, well, other than a nice syntactic separation between the 
> contracts and the body of the function, there's almost nothing I can do with 
> contracts that can't be done with a debug{} block in the function.
> 
> The problem boils down to this: no matter how well-defined I make my 
> contracts, they will never actually be tested until runtime.  At that point 
> there's no real benefit to doing stuff in an in{} block.  And since most of 
> the contents of the in{} block are asserts which disappear in release mode 
> anyway..
> 
> But -- if contracts, or at least portions of them, were able to be evaluated 
> at _compile time_ on functions (or individual parameters) that take constant 
> values, I could see a much larger benefit.
> 
> For example, say you have a function that takes a range of integers:
> 
> void fork(int x)
> in
> {
>     assert(x >= 0 && x < 20, "x is out of range");
> }
> body
> {
>     // use x!
> }
> 
> If I call fork(30), this is obviously an error, but won't be reported until 
> runtime, and even then, *only in debug mode*.
> 
> If, instead, the compiler used its CTFE mechanism to interpret the in{} 
> block as long as the params to the functions are constants, you'd get a nice 
> compile-time message, like:
> 
> error calling fork with parameters (30):
>     assertion (x >= 0 && x < 20) failed: "x is out of range"
> 
> And better yet, this would happen regardless of whether you're compiling in 
> debug mode or not.
> 
> It seems like a cool idea anyway.  I wonder, in practice, how often the 
> compiler would be able to evaluate the contracts, and if it would be of 
> practical use.  Or if there would be a better way to do this (like extending 
> the new template parameter constraints to functions: "void fork(int x) if(x 
>  >= 0 && x < 20)"). 
> 
> 

Sounds totally unnecessary.
if you pass 30 to the above fork you already know that it's not between
0 and 20 (that is if you finished 2nd grade of school). you need help
from the compiler when you do not know what x is, i.e. in run-time.
I don't see any practical benefits to this outside of meta-programming
and there I'd expect the compiler to throw the assert error during
compilation.

another issue is the removal of asserts in release mode. I'm not sure
that asserts should only work in debug mode and personally would prefer
to keep them in the released version. this probably should have a
compiler flag to control it. I don't like DMD's release and debug modes
at all and thing that the user should have a more fine grained control
over compilation. GCC allows me to define what kinds of optimizations I
want with a flag for each setting instead of a global release mode as
defined by Walter.
for example what if I'd like to compile my code with contracts and with
array bounds checking removed? How do I accomplish that?



More information about the Digitalmars-d mailing list