www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Contract programming syntax

reply bearophile <bearophileHUGS lycos.com> writes:
I like contract programming, it helps me avoid bugs. This is an example from
the docs:

long squareRoot(long x)
    in {
        assert(x >= 0);
    }

    out (result) {
        assert((result * result) <= x && (result+1) * (result+1) >= x);
    }

    body {
        return cast(long)std.math.sqrt(cast(real)x);
    }


But isn't a syntax like the following better? To me it looks more logic,
because in{} and out(){} are part of the function, and there's no need of a
special syntax for the body (and the 'body' keyword):

long squareRoot(long x) {
    in {
        assert(x >= 0);
    }

    out (result) {
        assert((result * result) <= x && (result+1) * (result+1) >= x);
    }

    return cast(long)std.math.sqrt(cast(real)x);
}

Bye,
bearophile
Apr 08 2009
next sibling parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 I like contract programming, it helps me avoid bugs. This is an example from
the docs:
 
 long squareRoot(long x)
     in {
         assert(x >= 0);
     }
 
     out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
 
     body {
         return cast(long)std.math.sqrt(cast(real)x);
     }
 
 
 But isn't a syntax like the following better? To me it looks more logic,
because in{} and out(){} are part of the function, and there's no need of a
special syntax for the body (and the 'body' keyword):
 
 long squareRoot(long x) {
     in {
         assert(x >= 0);
     }
 
     out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
 
     return cast(long)std.math.sqrt(cast(real)x);
 }
 
 Bye,
 bearophile

I agree, the 'body' keyword is the most useless thing in the language. I find it makes functions much harder to read. I hate my body.
Apr 08 2009
next sibling parent reply Kagamin <spam here.lot> writes:
Don Wrote:

 I agree, the 'body' keyword is the most useless thing in the language. I 
 find it makes functions much harder to read.
 I hate my body.

I second this.
Apr 08 2009
next sibling parent Robert Clipsham <robert octarineparrot.com> writes:
Jarrett Billingsley wrote:
  Wed, Apr 8, 2009 at 1:02 PM, Denis Koroskin <2korden gmail.com> wrote:
 On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:

 Don Wrote:

 I agree, the 'body' keyword is the most useless thing in the language. I
 find it makes functions much harder to read.
 I hate my body.



Fourthed. I also can't tell you how many times I wanted to use 'body' as a variable name :|

Call me a sheep, but... Fifthed. (is that even a word? :P)
Apr 08 2009
prev sibling parent reply =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= writes:
Jarrett Billingsley wrote:
  Wed, Apr 8, 2009 at 1:02 PM, Denis Koroskin <2korden gmail.com> wrote:
 On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:

 Don Wrote:

 I agree, the 'body' keyword is the most useless thing in the language. I
 find it makes functions much harder to read.
 I hate my body.



Fourthed. I also can't tell you how many times I wanted to use 'body' as a variable name :|

Fifthed. How about using bigfloat for that?
Apr 08 2009
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Danny Wilson wrote:
 2 x Fifthed + 1 = Eleventhed!

Don't you mean 2 × Fifthed + Firsted = Eleventhed ? Stewart.
Apr 09 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:

 Don Wrote:

 I agree, the 'body' keyword is the most useless thing in the language. I
 find it makes functions much harder to read.
 I hate my body.

I second this.

Thirded.
Apr 08 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
 Wed, Apr 8, 2009 at 1:02 PM, Denis Koroskin <2korden gmail.com> wrote:
 On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:

 Don Wrote:

 I agree, the 'body' keyword is the most useless thing in the language. I
 find it makes functions much harder to read.
 I hate my body.

I second this.

Thirded.

Fourthed. I also can't tell you how many times I wanted to use 'body' as a variable name :|
Apr 08 2009
prev sibling parent "Danny Wilson" <bluezenix gmail.com> writes:
2 x Fifthed + 1 = Eleventhed!

Op Wed, 08 Apr 2009 20:51:17 +0200 schreef Alexander Pánek  
<alexander.panek brainsware.org>:


 Fifthed. How about using bigfloat for that?

Apr 08 2009
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:gridbr$mv4$1 digitalmars.com...
I like contract programming, it helps me avoid bugs. This is an example 
from the docs:

 long squareRoot(long x)
    in {
        assert(x >= 0);
    }

    out (result) {
        assert((result * result) <= x && (result+1) * (result+1) >= x);
    }

    body {
        return cast(long)std.math.sqrt(cast(real)x);
    }


 But isn't a syntax like the following better? To me it looks more logic, 
 because in{} and out(){} are part of the function, and there's no need of 
 a special syntax for the body (and the 'body' keyword):

 long squareRoot(long x) {
    in {
        assert(x >= 0);
    }

    out (result) {
        assert((result * result) <= x && (result+1) * (result+1) >= x);
    }

    return cast(long)std.math.sqrt(cast(real)x);
 }

 Bye,
 bearophile

This is one of those things that has always kinda bugged me about the language, but I never really considered a big enough deal to bring up. But now that it has been brought up: Yes, I agree completely.
Apr 08 2009
next sibling parent Bill Baxter <wbaxter gmail.com> writes:
More agreement here.

--bb

On Thu, Apr 9, 2009 at 2:41 AM, Nick Sabalausky <a a.a> wrote:
 "bearophile" <bearophileHUGS lycos.com> wrote in message
 news:gridbr$mv4$1 digitalmars.com...
I like contract programming, it helps me avoid bugs. This is an example
from the docs:

 long squareRoot(long x)
 =A0 =A0in {
 =A0 =A0 =A0 =A0assert(x >=3D 0);
 =A0 =A0}

 =A0 =A0out (result) {
 =A0 =A0 =A0 =A0assert((result * result) <=3D x && (result+1) * (result+1=


 =A0 =A0}

 =A0 =A0body {
 =A0 =A0 =A0 =A0return cast(long)std.math.sqrt(cast(real)x);
 =A0 =A0}


 But isn't a syntax like the following better? To me it looks more logic,
 because in{} and out(){} are part of the function, and there's no need o=


 a special syntax for the body (and the 'body' keyword):

 long squareRoot(long x) {
 =A0 =A0in {
 =A0 =A0 =A0 =A0assert(x >=3D 0);
 =A0 =A0}

 =A0 =A0out (result) {
 =A0 =A0 =A0 =A0assert((result * result) <=3D x && (result+1) * (result+1=


 =A0 =A0}

 =A0 =A0return cast(long)std.math.sqrt(cast(real)x);
 }

 Bye,
 bearophile

This is one of those things that has always kinda bugged me about the language, but I never really considered a big enough deal to bring up. Bu=

 now that it has been brought up: Yes, I agree completely.

Apr 08 2009
prev sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Nick Sabalausky (a a.a)'s article
 "bearophile" <bearophileHUGS lycos.com> wrote in message
 news:gridbr$mv4$1 digitalmars.com...
I like contract programming, it helps me avoid bugs. This is an example
from the docs:

 long squareRoot(long x)
    in {
        assert(x >= 0);
    }

    out (result) {
        assert((result * result) <= x && (result+1) * (result+1) >= x);
    }

    body {
        return cast(long)std.math.sqrt(cast(real)x);
    }


 But isn't a syntax like the following better? To me it looks more logic,
 because in{} and out(){} are part of the function, and there's no need of
 a special syntax for the body (and the 'body' keyword):

 long squareRoot(long x) {
    in {
        assert(x >= 0);
    }

    out (result) {
        assert((result * result) <= x && (result+1) * (result+1) >= x);
    }

    return cast(long)std.math.sqrt(cast(real)x);
 }

 Bye,
 bearophile

language, but I never really considered a big enough deal to bring up. But now that it has been brought up: Yes, I agree completely.

while(oldContractSyntaxSucks) { // Currently evaluates to true. vote++; }
Apr 08 2009
parent Robert Clipsham <robert octarineparrot.com> writes:
dsimcha wrote:
 while(oldContractSyntaxSucks) {  // Currently evaluates to true.
     vote++;
 }

And always will do :D Proposed updated code: ---- while(currentContractSyntaxSucks) { // Currently evaluates to true. vote++; } complainAboutSomethingElse(); ----
Apr 08 2009
prev sibling next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
bearophile wrote:
 But isn't a syntax like the following better? To me it looks more logic,
because in{} and out(){} are part of the function, and there's no need of a
special syntax for the body (and the 'body' keyword):
 
 long squareRoot(long x) {
     in {
         assert(x >= 0);
     }
 
     out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
 
     return cast(long)std.math.sqrt(cast(real)x);
 }

No. This proposed syntax change is quite misleading. Contracts cannot access the function's local variables, but it looks like they can. Contracts are executed at particular times, but that syntax makes them look like they execute wherever they are written. I believe you can put "body" before each function body, even with no contracts, if it makes you happier.
 Bye,
 bearophile

Apr 08 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 8, 2009 at 4:51 PM, Christopher Wright <dhasenan gmail.com> wrote:
 No. This proposed syntax change is quite misleading. Contracts cannot access
 the function's local variables, but it looks like they can. Contracts are
 executed at particular times, but that syntax makes them look like they
 execute wherever they are written.

 I believe you can put "body" before each function body, even with no
 contracts, if it makes you happier.

OK, then what about: void foo() in { ... } out { ... } { ... } the 'body' keyword is completely arbitrary. There is no ambiguity here. Also, I almost never use contracts because of their verbosity. It's much shorter - and functionally equivalent - to just put asserts in the function body, some at the beginning and some in a scope(exit).
Apr 08 2009
next sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Jarrett Billingsley wrote:
 On Wed, Apr 8, 2009 at 4:51 PM, Christopher Wright <dhasenan gmail.com> wrote:
 No. This proposed syntax change is quite misleading. Contracts cannot access
 the function's local variables, but it looks like they can. Contracts are
 executed at particular times, but that syntax makes them look like they
 execute wherever they are written.

 I believe you can put "body" before each function body, even with no
 contracts, if it makes you happier.

OK, then what about: void foo() in { ... } out { ... } { ... } the 'body' keyword is completely arbitrary. There is no ambiguity here.

Agreed.
 Also, I almost never use contracts because of their verbosity.  It's
 much shorter - and functionally equivalent - to just put asserts in
 the function body, some at the beginning and some in a scope(exit).

Not technically true -- contract can contain more than raw asserts. For example, it might contain a non-trivial loop (such as a foreach which calls a virtual opApply) which may be hard for the compiler to optimize out even if it can deduce the body is a no-op (because it only contained assertions, most likely).
Apr 08 2009
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Jarrett Billingsley wrote:
 On Wed, Apr 8, 2009 at 4:51 PM, Christopher Wright <dhasenan gmail.com> wrote:
 No. This proposed syntax change is quite misleading. Contracts cannot access
 the function's local variables, but it looks like they can. Contracts are
 executed at particular times, but that syntax makes them look like they
 execute wherever they are written.

 I believe you can put "body" before each function body, even with no
 contracts, if it makes you happier.

OK, then what about: void foo() in { ... } out { ... } { ... }

I wouldn't mind that terribly.
 the 'body' keyword is completely arbitrary.  There is no ambiguity here.
 
 Also, I almost never use contracts because of their verbosity.  It's
 much shorter - and functionally equivalent - to just put asserts in
 the function body, some at the beginning and some in a scope(exit).

I use them with some frequency. I find their overhead to be minimal.
Apr 08 2009
prev sibling next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 09 Apr 2009 00:51:49 +0400, Christopher Wright <dhasenan gmail.com>
wrote:

 bearophile wrote:
 But isn't a syntax like the following better? To me it looks more  
 logic, because in{} and out(){} are part of the function, and there's  
 no need of a special syntax for the body (and the 'body' keyword):
  long squareRoot(long x) {
     in {
         assert(x >= 0);
     }
      out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
      return cast(long)std.math.sqrt(cast(real)x);
 }

No. This proposed syntax change is quite misleading. Contracts cannot access the function's local variables, but it looks like they can. Contracts are executed at particular times, but that syntax makes them look like they execute wherever they are written. I believe you can put "body" before each function body, even with no contracts, if it makes you happier.
 Bye,
 bearophile


Does scope(exit) also make you feel that it is executed immediately? I see nothing wrong with local variables to be available in "out", but in most cases "out" is defined /before/ function body so no variables will be visible this way. It also looks like you can have multiple in{} and out{} sections this way. This is a nice bonus, btw!
Apr 08 2009
parent reply Christopher Wright <dhasenan gmail.com> writes:
Denis Koroskin wrote:
 On Thu, 09 Apr 2009 00:51:49 +0400, Christopher Wright 
 <dhasenan gmail.com> wrote:
 
 bearophile wrote:
 But isn't a syntax like the following better? To me it looks more 
 logic, because in{} and out(){} are part of the function, and there's 
 no need of a special syntax for the body (and the 'body' keyword):
  long squareRoot(long x) {
     in {
         assert(x >= 0);
     }
      out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
      return cast(long)std.math.sqrt(cast(real)x);
 }

No. This proposed syntax change is quite misleading. Contracts cannot access the function's local variables, but it looks like they can. Contracts are executed at particular times, but that syntax makes them look like they execute wherever they are written. I believe you can put "body" before each function body, even with no contracts, if it makes you happier.
 Bye,
 bearophile


Does scope(exit) also make you feel that it is executed immediately?

Well, take this example: void foo(int i) { if (i < 0) return; scope (exit) logExit; } The position has meaning here. Then take this example: void foo(int i) { if (i < 0) return; in { assert (i != -1; } } This is confusing. Good style dictates that your contracts should be separated from the body of your function, though. The bigger issue is the apparent nesting of scopes.
Apr 08 2009
parent reply Christopher Wright <dhasenan gmail.com> writes:
Jarrett Billingsley wrote:
 On Wed, Apr 8, 2009 at 6:38 PM, Christopher Wright <dhasenan gmail.com> wrote:
 
 Then take this example:

 void foo(int i)
 {
   if (i < 0) return;
   in { assert (i != -1; }
 }

 This is confusing.

There's a simple solution: define the function body grammar to only allow in{} and out{} blocks at the beginning of the function, before any statements.

Or just your style guide. But even if you can demonstrate significant benefits (and I don't see any benefits, really), inertia is against you. I don't think Walter would change it for anything but extreme provocation.
Apr 08 2009
parent Don <nospam nospam.com> writes:
Jarrett Billingsley wrote:
 On Wed, Apr 8, 2009 at 10:59 PM, Christopher Wright <dhasenan gmail.com> wrote:
 Or just your style guide. But even if you can demonstrate significant
 benefits (and I don't see any benefits, really), inertia is against you. I
 don't think Walter would change it for anything but extreme provocation.

Are you suggesting an "offer he can't refuse"? ;)

With the pressure to reduce the number of keywords in D, body is the most obvious candidate. It's identical to /*body*/ as far as I can tell.
Apr 08 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 8, 2009 at 5:32 PM, Frits van Bommel
<fvbommel remwovexcapss.nl> wrote:
 Not technically true -- contract can contain more than raw asserts.
 For example, it might contain a non-trivial loop (such as a foreach which
 calls a virtual opApply) which may be hard for the compiler to optimize out
 even if it can deduce the body is a no-op (because it only contained
 assertions, most likely).

Sure, but most of my contracts are composed entirely of asserts. And there's always the debug{} block.
Apr 08 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 8, 2009 at 6:38 PM, Christopher Wright <dhasenan gmail.com> wro=
te:

 Then take this example:

 void foo(int i)
 {
 =A0 if (i < 0) return;
 =A0 in { assert (i !=3D -1; }
 }

 This is confusing.

There's a simple solution: define the function body grammar to only allow in{} and out{} blocks at the beginning of the function, before any statements.
Apr 08 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Wed, Apr 8, 2009 at 10:59 PM, Christopher Wright <dhasenan gmail.com> wrote:
 Or just your style guide. But even if you can demonstrate significant
 benefits (and I don't see any benefits, really), inertia is against you. I
 don't think Walter would change it for anything but extreme provocation.

Are you suggesting an "offer he can't refuse"? ;)
Apr 08 2009
prev sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Apr 9, 2009 at 2:56 AM, Don <nospam nospam.com> wrote:
 Jarrett Billingsley wrote:
 On Wed, Apr 8, 2009 at 10:59 PM, Christopher Wright <dhasenan gmail.com>
 wrote:
 Or just your style guide. But even if you can demonstrate significant
 benefits (and I don't see any benefits, really), inertia is against you=



 I
 don't think Walter would change it for anything but extreme provocation=



 Are you suggesting an "offer he can't refuse"? =A0;)

With the pressure to reduce the number of keywords in D, body is the most obvious candidate. It's identical to /*body*/ as far as I can tell.

Oh. I was kind of thinking a horse head in his bed.
Apr 09 2009
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Wed, 08 Apr 2009 10:46:19 -0400, bearophile wrote:

 But isn't a syntax like the following better? To me it looks more logic,
 because in{} and out(){} are part of the function, and there's no need 
 of a special syntax for the body (and the 'body' keyword):

Yes! I've never been happen with the awkwardness of the current syntax. It looks just plain wrong and certainly not intuitive or helpful when reading code. And as you suggest 'in' and 'out' are already special words (and Walter has a special love for overloading keywords) so 'body' isn't needed in your suggestion. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Apr 08 2009
prev sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-04-08 10:46:19 -0400, bearophile <bearophileHUGS lycos.com> said:

 I like contract programming, it helps me avoid bugs. This is an example 
 from the docs:
 
 long squareRoot(long x)
     in {
         assert(x >= 0);
     }
 
     out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
 
     body {
         return cast(long)std.math.sqrt(cast(real)x);
     }
 
 But isn't a syntax like the following better?
 To me it looks more logic, because in{} and out(){} are part of the 
 function, and there's no need of a special syntax for the body (and the 
 'body' keyword):
 
 long squareRoot(long x) {
     in {
         assert(x >= 0);
     }
 
     out (result) {
         assert((result * result) <= x && (result+1) * (result+1) >= x);
     }
 
     return cast(long)std.math.sqrt(cast(real)x);
 }

I believe the syntax should make the contracts part of the function signature, not part of the function body, because contracts are about expressing the function's interface. So I disagree with your proposed syntax which puts the contracts as part of the body. I do agree however that reserving 'body' as a keyword is from time to time hindering. I'd certainly welcome a change if it allows removing 'body' as a keyword. But not this one, because it puts the contract at the wrong place. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 08 2009
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Michel Fortin wrote:
<snip>
 I believe the syntax should make the contracts part of the function 
 signature, not part of the function body, because contracts are about 
 expressing the function's interface. So I disagree with your proposed 
 syntax which puts the contracts as part of the body.

Finally, a counter-argument with which I agree. Moreover, having in/out contracts as part of the function body suggests that they are part of what is overridden. But the language doesn't quite work like that. http://d.puremagic.com/issues/show_bug.cgi?id=302 http://www.digitalmars.com/d/archives/digitalmars/D/31595.html Moreover, it ought to be possible to put contracts on abstract or interface methods. This wouldn't fit in with contracts being in the body. Stewart.
Apr 09 2009
parent Kagamin <spam here.lot> writes:
Stewart Gordon Wrote:

 Finally, a counter-argument with which I agree.  Moreover, having in/out 
 contracts as part of the function body suggests that they are part of 
 what is overridden.  But the language doesn't quite work like that.

I thought, they're overriden.
Apr 09 2009