[Issue 9300] Syntax for loop invariants
    d-bugmail at puremagic.com 
    d-bugmail at puremagic.com
       
    Tue Feb  5 04:21:48 PST 2013
    
    
  
http://d.puremagic.com/issues/show_bug.cgi?id=9300
--- Comment #2 from bearophile_hugs at eml.cc 2013-02-05 04:21:47 PST ---
(In reply to comment #1)
Thank you for your answers.
> Loop invariants were part of the D spec, a long time ago.
I didn't know this.
> Compared to an assert, plus a comment, what do they add?
> 
>    while (cond) 
>    {
>        // Loop invariant
>        assert( xxx );
>        ...
>    }
Now think about adding some more parts to that while loop, with one or more
"continue". Now where do you put that assert? You have to duplicate your
assert:
   while (cond) 
   {
       if (predicate()) {
           assert( xxx ); // Loop invariant
           continue;
       }
       ... // some code here
       assert( xxx ); // Loop invariant
       ...
   }
If instead of an assert you have more code (maybe inside a scope {}) your code
gets redundant.
A invariant{} piece of code is guaranteed by the compiler to be run in the
right moment of the loop, just like out(){} is guaranteed to be run after every
return contained in a function. This frees the programmer from the need to
think where to put the loop invariant.
> For example, it's easy for a
> static analysis tool to recognize this as a loop invariant.
Take a look here, this loop has both loop invariant code and a free assert(r <
x) that's not part of the invariant. Is your static analysis tool so able to
tell them apart?
int iLog2(in int x) pure nothrow @safe
in {
    assert(x >= 1);
} out(result) {
    assert(result >= 0);
    assert((1 << result) <= x);
} body {
    int r = 0;
    int y = x;
    while (y > 1) 
        invariant() {
            assert(y >= 1 && r >= 0);
            assert(y * (1 << r) <= x);
        } body {
            y /= 2;
            assert(r < x); // Regular assert.
            r++;
        }
    return r;
}
> And I don't think you'll find a syntax that is nicer
> than what I wrote above!
Your example is too much simple and short.
And generally it's good to have ways to communicate semantics to the compiler,
instead of using a comment.
And it's not just a matter of compilers: having a built-in syntax encourages
people to take it in account. I have met people that didn't know about contract
programming before seeing the D syntax for contracts. Sometimes having a syntax
is a way to teach something to programmers.
A programmer is supposed to know what a loop invariant (and variant) is, but if
you offer them a syntax staple I think they will be a bit more willing to think
about loop invariants. A syntax gives a frame for the mind to think about that.
All D books and tutorials will have a chapter about loop invariants, this will
raise the awareness about those invariants. Even if only high-grade D programs
will have loop invariants, it will be an improvement.
I think the amount of new syntax required by this enhancement request is quite
small.
-- 
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