digitalmars.D - Contract programming syntax
- bearophile (23/23) Apr 08 2009 I like contract programming, it helps me avoid bugs. This is an example ...
- Don (4/36) Apr 08 2009 I agree, the 'body' keyword is the most useless thing in the language. I...
- Kagamin (2/5) Apr 08 2009 I second this.
- Denis Koroskin (2/7) Apr 08 2009 Thirded.
- Jarrett Billingsley (3/12) Apr 08 2009 Fourthed. I also can't tell you how many times I wanted to use 'body'
- Robert Clipsham (3/17) Apr 08 2009 Call me a sheep, but...
- =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= (2/16) Apr 08 2009 Fifthed. How about using bigfloat for that?
- Danny Wilson (3/4) Apr 08 2009 2 x Fifthed + 1 = Eleventhed!
- Stewart Gordon (5/6) Apr 09 2009 Don't you mean
- Nick Sabalausky (5/31) Apr 08 2009 This is one of those things that has always kinda bugged me about the
- Bill Baxter (7/47) Apr 08 2009 More agreement here.
- dsimcha (4/44) Apr 08 2009 while(oldContractSyntaxSucks) { // Currently evaluates to true.
- Robert Clipsham (9/12) Apr 08 2009 And always will do :D
- Christopher Wright (7/22) Apr 08 2009 No. This proposed syntax change is quite misleading. Contracts cannot
- Jarrett Billingsley (10/16) Apr 08 2009 OK, then what about:
- Frits van Bommel (6/26) Apr 08 2009 Not technically true -- contract can contain more than raw asserts.
- Jarrett Billingsley (4/9) Apr 08 2009 Sure, but most of my contracts are composed entirely of asserts. And
- Christopher Wright (3/23) Apr 08 2009 I use them with some frequency. I find their overhead to be minimal.
- Denis Koroskin (4/25) Apr 08 2009 Does scope(exit) also make you feel that it is executed immediately?
- Christopher Wright (18/47) Apr 08 2009 Well, take this example:
- Jarrett Billingsley (5/12) Apr 08 2009 There's a simple solution: define the function body grammar to only
- Christopher Wright (4/19) Apr 08 2009 Or just your style guide. But even if you can demonstrate significant
- Jarrett Billingsley (2/5) Apr 08 2009 Are you suggesting an "offer he can't refuse"? ;)
- Don (3/9) Apr 08 2009 With the pressure to reduce the number of keywords in D, body is the
- Jarrett Billingsley (4/17) Apr 09 2009 .
- bearophile (4/5) Apr 08 2009 You are right, thank you.
- Derek Parnell (11/14) Apr 08 2009 Yes!
- Michel Fortin (13/45) Apr 08 2009 I believe the syntax should make the contracts part of the function
-
Stewart Gordon
(11/15)
Apr 09 2009
- Kagamin (2/5) Apr 09 2009 I thought, they're overriden.
- Tomasz Sowiński (8/20) Apr 09 2009 I like removing "body". But maybe we can make contracts a bit nicer by r...
- Stewart Gordon (10/18) Apr 09 2009 Probably not, but I'm not sure I like it at all. Firstly, it reminds me...
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
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, bearophileI 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
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
On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:Don Wrote:Thirded.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
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:Fourthed. I also can't tell you how many times I wanted to use 'body' as a variable name :|Don Wrote:Thirded.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
Jarrett Billingsley wrote:Wed, Apr 8, 2009 at 1:02 PM, Denis Koroskin <2korden gmail.com> wrote:Call me a sheep, but... Fifthed. (is that even a word? :P)On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:Fourthed. I also can't tell you how many times I wanted to use 'body' as a variable name :|Don Wrote:Thirded.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
Jarrett Billingsley wrote:Wed, Apr 8, 2009 at 1:02 PM, Denis Koroskin <2korden gmail.com> wrote:Fifthed. How about using bigfloat for that?On Wed, 08 Apr 2009 20:01:46 +0400, Kagamin <spam here.lot> wrote:Fourthed. I also can't tell you how many times I wanted to use 'body' as a variable name :|Don Wrote:Thirded.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
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
Danny Wilson wrote:2 x Fifthed + 1 = Eleventhed!Don't you mean 2 × Fifthed + Firsted = Eleventhed ? Stewart.
Apr 09 2009
"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, bearophileThis 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
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...) >=3D x);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=f=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=) >=3D x);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=t=A0 =A0} =A0 =A0return cast(long)std.math.sqrt(cast(real)x); } Bye, bearophileThis 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
== Quote from Nick Sabalausky (a a.a)'s article"bearophile" <bearophileHUGS lycos.com> wrote in message news:gridbr$mv4$1 digitalmars.com...while(oldContractSyntaxSucks) { // Currently evaluates to true. vote++; }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, bearophileThis 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
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
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
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
Jarrett Billingsley wrote:On Wed, Apr 8, 2009 at 4:51 PM, Christopher Wright <dhasenan gmail.com> wrote:Agreed.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).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
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
Jarrett Billingsley wrote:On Wed, Apr 8, 2009 at 4:51 PM, Christopher Wright <dhasenan gmail.com> wrote:I wouldn't mind that terribly.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).I use them with some frequency. I find their overhead to be minimal.
Apr 08 2009
On Thu, 09 Apr 2009 00:51:49 +0400, Christopher Wright <dhasenan gmail.com> wrote:bearophile wrote: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!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
Denis Koroskin wrote:On Thu, 09 Apr 2009 00:51:49 +0400, Christopher Wright <dhasenan gmail.com> wrote: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.bearophile wrote:Does scope(exit) also make you feel that it is executed immediately?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
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
Jarrett Billingsley wrote:On Wed, Apr 8, 2009 at 6:38 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.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.
Apr 08 2009
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
Jarrett Billingsley wrote:On Wed, Apr 8, 2009 at 10:59 PM, Christopher Wright <dhasenan gmail.com> wrote: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.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
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=Oh. I was kind of thinking a horse head in his bed.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.
Apr 09 2009
Christopher Wright:Contracts cannot access the function's local variables, but it looks like they can.<You are right, thank you. Bye, bearophile
Apr 08 2009
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
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
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.<snip> 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
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
Jarrett Billingsley Wrote: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).I like removing "body". But maybe we can make contracts a bit nicer by removing braces if the contract contains only one statement: void foo() in assert(something); out assert(something_else); { ... } would that be ambiguous to the compiler? Tomek
Apr 09 2009
<snip>I like removing "body". But maybe we can make contracts a bit nicer by removing braces if the contract contains only one statement: void foo() in assert(something); out assert(something_else); { ... } would that be ambiguous to the compiler?Probably not, but I'm not sure I like it at all. Firstly, it reminds me of the old crocky C syntax for declaring parameter types. Secondly, if we're going to allow contracts on abstract/interface functions, would you need to write two semicolons in a row with this syntax? (Maybe there's no need for a semicolon in lieu of the body in such cases. It's just what the compiler used to allow, though it never actually did anything with the contracts.) Stewart.
Apr 09 2009