DIP 1009--Improve Contract Usability--Preliminary Review Round 1
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Tue Jun 20 14:04:16 PDT 2017
On 6/20/17 1:42 PM, H. S. Teoh via Digitalmars-d wrote:
> On Tue, Jun 20, 2017 at 11:57:55AM +0000, Mike Parker via Digitalmars-d wrote:
>> DIP 1009 is titled "Improve Contract Usability".
>>
>> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1009.md
> [...]
>
> What would a body-less declaration of a function look like under the new
> syntax? Hopefully not this:
>
> int myFunc(Args...)(Args args)
> if (Args.length > 2)
> in assert(args[0] != 0); // semicolon: ouch
> in assert(args[1] > 1); // semicolon: ouch
> // How do we end the declaration here? Another semicolon?
> ; // ouch
>
> Having several semicolons outside a braced block makes declarations
> harder to parse. External tools will no longer be able to just scan for
> top-level semicolons to find the end of the declaration, but will have
> to understand contract syntax too, even if that particular tool doesn't
> care about contracts.
>
> It gets worse if your contract involves calling another function; you'll
> end up with:
>
> int myFunc(Args...)(Args args)
> if (Args.length > 2)
> in assert(args[0] != 0); // is this the end of the declaration?
> in otherFunc(args[0]); // is this declaring another function?
> // (i.e., a typo of int -> in?)
> ; // ouch
>
> Also, I don't like the idea of putting contracts inside the function
> body. As the DIP already mentions, this makes parsing of contracts more
> difficult. It also causes cognitive dissonance (contracts are a part of
> the function's signature, not its implementation).
>
> It's even worse if you allow contracts in arbitrary places inside the
> function body -- then even somebody reading the code wouldn't know, at a
> glance, what the contracts are, without scanning the entire function
> body! That makes contracts *harder* to read and use, rather than easier,
> in direct contradiction of the purpose of this DIP.
>
>
> Here's my counter-proposal: since the sig constraint line uses
> parentheses (and yes, I deliberately planted a sig constraint above just
> to make this point), why not go for syntactical symmetry? I.e., like
> this:
>
> int myFunc(Args...)(Args args)
> if (Args.length > 2)
> in (args[0] != 0)
> in (args[1] > 1); // one semicolon to end them all
This is much much better. The verbosity of contracts isn't really the
brace, it's the asserts. This also gives the compiler a better handle on
what causes the thing to fail (better error message).
Note that you NEED the semicolon for the DIP's proposal, because `in` is
also a binary operator, and could be misinterpreted. With yours, it's
not possible to misinterpret.
> For out-contracts, we could use the existing lambda syntax to avoid the
> ugliness of having two parenthesized expressions next to each other:
>
> // Body-less declaration
> int myFunc(Args...)(Args args)
> if (Args.length > 1)
> in (args[0] > 0)
> out (result => result > 10);
> // N.B.: instead of: `out(result)(result > 10)` which is uglier.
>
> // Full declaration
> int myFunc(Args...)(Args args)
> if (Args.length > 1)
> in (args[0] > 0)
> out (result => result > 10)
> {
> ... // function body goes here
> }
I'm not understanding that last part. Current syntax would be:
out(result)
{
// check result
}
I'm concerned this would be ambiguous with the current syntax.
IMO, this whole proposal doesn't carry enough weight, either your
version or the DIP itself. I would not be in favor. Current syntax is
understandable, and not too verbose IMO.
-Steve
More information about the Digitalmars-d
mailing list