On Fri, 25 Mar 2011 16:23:08 -0400, spir <denis.s...@gmail.com> wrote:

This logic certainly looks sensible, but I cannot understand how it should work in practice. Say I'm implementing a little set of operations on decimals. Among those, some (division, square root...) will necessarily have to check their input.

You can look at it in a simple way: If this branch of code will always run the same way every time (i.e. is deterministic), then using assert is desired. Why? Because the assumption is that you test that code via unit tests. Once you test it, and it works, there is no reason to test it again.

For example, if I do:

sqrt(1);

There is never ever a need to test this in production code. sqrt(1) is always 1, and will always work.

If I do:

sqrt(-1);

There is never ever a need to test this in production code. sqrt(-1) is always a failure, and will always fail. Unit tests should catch this code before it is released.

But if I do something like:

auto file = File.open("/tmp/xyz.txt"); // did not look up usage for File, may be wrong

Then I always want this to be tested, even in release mode, because there are environments beyond the program's control that will cause an error. Similar to this, user input needs to be validated even in production code.

So if you had:

int main(string[] args)
{
sqrt(to!int(args[0]));
}

this means args[0] should be checked that it is a valid positive integer.

The problem with this whole utopian idea is, the code that is responsible for knowing how to check its input is the function. The code that knows whether the input needs to be checked during release is the caller. So there is no way to convey to sqrt "hey, this input I'm sending in is externally-generated, check it during production too, ok?". If we had options for that, the API quickly becomes unwieldly.

Of course, knowing that sqrt takes only positive numbers, we could do this check outside the sqrt function, but far more complex functions may not be so easy to validate input for. And why should the caller be responsible for validating the input?

What I feel like we need is a compiler feature like:

validate(sqrt(to!int(args[0]));

which essentially calls sqrt with asserts and contracts *enabled*, even at production time. This way you could choose while writing code how essential a particular call is to check the input, but re-use the already-in-place contracts for that function.

This might be a feature that's totally not worth the effort. But I can't see a good way to solve this without having some sort of mechanism. It also shouldn't throw an AssertError, since that would kill the program instantly.

-Steve

Reply via email to