Idea: function contracts + CTFE

Jarrett Billingsley kb3ctd2 at yahoo.com
Fri Jun 20 11:47:49 PDT 2008


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)"). 





More information about the Digitalmars-d mailing list