On Thursday, 22 June 2017 at 06:43:38 UTC, H. S. Teoh wrote:
On Thu, Jun 22, 2017 at 05:46:06AM +0000, MysticZach via
Digitalmars-d wrote: [...]
As far as syntax subtrees not belonging to their parent, I can
see where the cognitive dissonance comes from. But it just
doesn't seem that bad to me, since contracts are always
executed as if they are sequential statements anyway.
[...]
Then possibly you're missing the point behind DbC. The idea of
"executing" a contract seems to indicate that you're taking the
current D implementation of it as normative.
I understand. Thus, a better DIP would suggest reimplementing D's
DbC system altogether. Because as it is, they are little more
than syntax dressing, which happens to be less convenient that
just writing out the asserts in the first place. They're more
like syntax _vinegar_ than sugar. Which explains why hardly
anyone uses them. Why write this:
int fun(int a)
in { assert (a); }
do {
return a;
}
...when you could just do this:
int fun(int a) {
assert(a);
return a;
}
With your improvement, it's a little better,
int fun(int a)
in (a)
{
return a;
}
...but the cost is that `assert` is implied, and no other system
of checking is allowed, which seems like a sufficient flaw to
make it not decisively better. To solve this, you'd have to
decouple `assert` from the contract, requiring this:
int fun(int a)
in (assert(a))
{
return a;
}
This also looks good. But now the grammar is weird because it's
just an expression in there without a statement, which doesn't
happen anywhere else in D.
I start to get the nagging feeling that your point about the
limitation in D's DbC implementation is actually the fatal flaw
here. It's currently _illegal_ (outside of interface
declarations) to expose the signature separately from the body,
which, as you point out, is more or less the whole point of DbC.
<shrug> The existing system is itself distinctly _worse_ than
just writing out asserts manually... and as far as I can tell,
none of the alternative syntaxes is a decisive improvement over
it. Yours looks the best, but implying `assert` in the grammar
seems to be going too far, especially for a DbC system that is
only half functional. If the `assert` system were made more
user-definable, it would make more sense. Do you agree with me on
this?
Plans to improve `assert` are already in the air. Maybe we should
wait on them before promoting your suggestion?