[Issue 6857] Precondition contract checks should be statically bound.

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu May 3 10:44:10 PDT 2012


http://d.puremagic.com/issues/show_bug.cgi?id=6857



--- Comment #14 from deadalnix <deadalnix at gmail.com> 2012-05-03 10:45:19 PDT ---
(In reply to comment #13)
> I apologize but I still think the confusion goes the other way. A good way to
> arbiter this is to peruse the literature on the subject, as Walter suggested.
> If going through a book has too much overhead, online articles and
> presentations should work, too. I can't afford to do much more explaining than
> essentially reciting material that's out there. For example I'd recommend this:
> http://www.cs.ucsb.edu/~bultan/courses/272-F08/lectures/Contract.ppt. Slides 19
> and 20 should clarify the matter.

I did read your document with attention, and looked for some other resources
today. That arguments given in such documents validate both the current state
of thing and the proposed new behavior.

In fact, I have failed to find any documentation/article/whatever about the
corner case where both behavior differs.

In other terms, as it seems that the corner case hasn't been considered, the
proposed solution is *A* solution and not *THE* solution. As, according to
given arguments I have found in literature, both behavior are good.

If I restate arguments they goes like this :
 - B can be written way after fizzbuzzA, so shouldn't be able to provide an in
contract that break it.
 - Instance of B can be passed to any code that expect instance of A, so B in
contracts can only loosen contract provided by A, not restrict them.

I think we all agree on such points. I think we can all agree also that both
current behavior and proposed behavior satisfy constraints expressed here.

The only case where things differs is the one given as example above. Let's
remove the ... to make it fully explicit.

class A {
    void foo(int x) in { assert(x > 0); } body {}
}

class B : A {
    void foo(int x) in { assert(x > -2); } body {}
}

and the function

void fizzbuzz(A a) {
    a.foo(-1);
}

If I do fizzbuzz(new B()); The current behavior will not raise any error. But,
as we see in fizzbuzz's body, it doesn't because the object is of type B, not
of type A, because any other instances of subtypes of A or A can cause the
fizzbuzz function to fail.

We conclude that the fizzbuzz function is only correct if it DOES KNOW that it
is manipulating object of type B, because operation done are invalid on object
of type A.

The erratic behavior of fizzbuzz will not be spotted if I pass an instance of B
to fizzbuzz. Still, the code is flawed and waiting to explode any time in the
future. The whole point of contract is to spot such a situation.

For valid code, both behavior allow the same thing exactly. The proposed
behavior allow to spot MORE problems EARLIER, and it is something you want.

The only reason fizzbuzz here is correct if because the programmer KNOW only
instances of B will be passed to fizzbuzz.

I may be wrong, but I'd be happy to discuss that specific case, instead of
relying on documentation that do not talk about it. I failed in finding
documentation about that specific corner case.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list