digitalmars.D - Contract programming syntax
- bearophile <bearophileHUGS lycos.com> Apr 08 2009
- Don <nospam nospam.com> Apr 08 2009
- Kagamin <spam here.lot> Apr 08 2009
- Robert Clipsham <robert octarineparrot.com> Apr 08 2009
- =?UTF-8?B?QWxleGFuZGVyIFDDoW5law==?= Apr 08 2009
- Stewart Gordon <smjg_1998 yahoo.com> Apr 09 2009
- "Denis Koroskin" <2korden gmail.com> Apr 08 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Apr 08 2009
- "Danny Wilson" <bluezenix gmail.com> Apr 08 2009
- "Nick Sabalausky" <a a.a> Apr 08 2009
- Bill Baxter <wbaxter gmail.com> Apr 08 2009
- dsimcha <dsimcha yahoo.com> Apr 08 2009
- Robert Clipsham <robert octarineparrot.com> Apr 08 2009
- Christopher Wright <dhasenan gmail.com> Apr 08 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Apr 08 2009
- Frits van Bommel <fvbommel REMwOVExCAPSs.nl> Apr 08 2009
- Christopher Wright <dhasenan gmail.com> Apr 08 2009
- "Denis Koroskin" <2korden gmail.com> Apr 08 2009
- Christopher Wright <dhasenan gmail.com> Apr 08 2009
- Christopher Wright <dhasenan gmail.com> Apr 08 2009
- Don <nospam nospam.com> Apr 08 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Apr 08 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Apr 08 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Apr 08 2009
- Jarrett Billingsley <jarrett.billingsley gmail.com> Apr 09 2009
- Derek Parnell <derek psych.ward> Apr 08 2009
- Michel Fortin <michel.fortin michelf.com> Apr 08 2009
- Stewart Gordon <smjg_1998 yahoo.com> Apr 09 2009
- Kagamin <spam here.lot> Apr 09 2009
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, 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
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
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
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
Danny Wilson wrote:2 x Fifthed + 1 = Eleventhed!
Don't you mean 2 × Fifthed + Firsted = Eleventhed ? Stewart.
Apr 09 2009
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
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
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
"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
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
== 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
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: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
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
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
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
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
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
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
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
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
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
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.
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









Robert Clipsham <robert octarineparrot.com> 