DIP 1009--Improve Contract Usability--Preliminary Review Round 1
Moritz Maxeiner via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jun 21 04:53:35 PDT 2017
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 (allegedly) allows recovery of bugs
I would consider these as niche cases that are already 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;
template validateContract(T) if (isInputContract!T ||
isOutputContract!T)
{
version (ValidateContracts) void violated(ref T contract)
{
import core.stdc.stdlib : _Exit;
debug printDebugInfo(contract);
else printFileAndLIne(contract);
if (onContractViolation !is null) onContractViolation();
_Exit(1); // without scope guard since
onContractViolation is `nothrow`
}
static if (isInputContract!T) {
void validateContract(T contract)
{
version (ValidateContracts) if (!contract)
violated(contract);
}
} else {
void validateContract(T contract, T.ResultType result)
{
version (ValidateContracts) if (!contract(result))
violated(contract);
}
}
}
---
More information about the Digitalmars-d
mailing list