On 03/25/2011 09:49 PM, Steven Schveighoffer wrote:
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

I agree with all of this. But here you're the client of sqrt. What if you implement it (or for a new numeric type)? You'll need to catch param errors for /input/ to your func (not for args you /provide/ to a third party func). That was my case.

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.

Agreed. Anyway, validating input, wherever it comes from, as soon as possible, is certainly better practice. (obviously makes debugging easier)

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.

Same for me. I'd like to find a language that implements this and see how the feature stands in front of real situations, and on the long run (remember java's checked expections ;-)

Denis
--
_________________
vita es estrany
spir.wikidot.com

Reply via email to