On Wednesday, 21 June 2017 at 09:10:33 UTC, MysticZach wrote:
On Wednesday, 21 June 2017 at 05:19:26 UTC, H. S. Teoh wrote:
On Wed, Jun 21, 2017 at 01:06:40AM +0000, MysticZach via
Digitalmars-d wrote:
On Tuesday, 20 June 2017 at 21:04:16 UTC, Steven
Schveighoffer wrote:
> This is much much better. The verbosity of contracts isn't
> really the brace, it's the asserts.
I think it's both, and I think the brace is the only thing
that can be improved upon. How could you justify insisting
that everyone use the built-in asserts for their contracts?
[...]
Umm... I think we're not quite on the same page here. What
*else* are people supposed to use inside their contracts
besides the built-in assert??
Many people have expressed discontent with existing asserts. In
fact, they were just changed yesterday to address one of these
concerns:
https://github.com/dlang/dmd/pull/6901
Just my two cents, again: DbC prohibits broken contracts, i.e.
any violation is a bug. From my point of view, a broken contract
in the simple syntax as proposed by H.S.Teoh, should by default
- in debug mode: Give you debug information (stack trace, etc.)
then terminate
- in release mode: Print file and line number and then terminate
No cleanup by default.
People I've observed voicing issues with assert have happened to
fall into one of these three categories:
- People who agree with the terminate approach, but want custom
cleanup
I remain skeptical about the sanity of calling arbitrary code
with the knowledge of a previously triggered bug (in release
mode), but that can be easily addressed by allowing to register a
hook that gets called on contract violations; the process will
still terminate after the hook is finished, though.
- People whose use cases supposedly allows recovery of bugs
These are niche cases that can be covered by the preexisting
verbose syntax: `in { if (!cond) throw Exception(); }`. I would
simply not include support for that in the easy-to-read variant.
- People who use assert (or other Errors) for user input
validation
That's not what they are for.
To sum it up, I would like semantics similar to this (simplified
code) for this syntax:
---
void delegate() @nothrow onContractViolation;
void validateContract(bool)(lazy bool cond)
{
version (CheckContracts) if (!cond)
{
import core.stdc.stdlib : _Exit;
debug printDebugInfo(...);
else printFileAndLIne();
{
if (onContractViolation !is null)
onContractViolation();
_Exit(1);
} else {
print
}
}
}
---