April 07, 2018
On Friday, 6 April 2018 at 21:31:42 UTC, Zach Tollen wrote:
>
> I think we've now given Design-by-Contract a really good chance of becoming commonly used in the D wild. Let's see what happens!
>

Although https://dlang.org/spec/contracts.html will surely be updated with this new syntax, I think a blog post would also help in this regard, I think.

Jordan
April 07, 2018
On Saturday, 7 April 2018 at 20:06:19 UTC, Jordan Wilson wrote:
> Although https://dlang.org/spec/contracts.html will surely be updated with this new syntax, I think a blog post would also help in this regard, I think.
>
> Jordan

That's a good idea. I'll start on one.
April 09, 2018
On Saturday, 7 April 2018 at 16:10:41 UTC, Jacob Carlborg wrote:
> What's the philosophy around accepted DIPs containing multiple suggestions/alternatives. For example, this DIP mentions three alternatives for the "out" syntax [1], it's not crystal clear which one was actually accepted.

I think the philosophy is just that it's good to record the thought process which led in the final suggestion. The DIP does recommend syntax option 3 for "out" contracts, which is also the only one described in the grammar. This could be clearer, but now I want to change the language spec, which obviously matters a whole lot more, now that the DIP has been accepted.
April 09, 2018
On 07.04.2018 00:45, Timon Gehr wrote:
> On 06.04.2018 19:36, H. S. Teoh wrote:
>> On Fri, Apr 06, 2018 at 05:02:54PM +0000, Adam D. Ruppe via Digitalmars-d-announce wrote:
>>> On Friday, 6 April 2018 at 16:57:21 UTC, Jonathan M Davis wrote:
>>>> Now, if the contracts ended up in the documentation or something
>>>
>>> My documentation generator supports contracts, but I found in
>>> practice, most of them are so illegible it doesn't actually help any
>>> to include them, so I never do.
>>>
>>> But if they were simpler single expressions, it might make sense to
>>> revisit that.
>>
>> Yeah, I think having expression syntax will make contracts more
>> readable.  We'll just have to see.
>>
>> When will this DIP be implemented? AIUI Timon already has an
>> implementation sitting around somewhere.  Can't wait for it to get
>> merged...
>>
>>
>> T
>>
> 
> I'll rebase it against master and create a pull request ASAP.

I created a pull request: https://github.com/dlang/dmd/pull/8155

It took a while to rebase, as relevant parts of the compiler have been refactored in the meantime.
April 11, 2018
On Friday, 6 April 2018 at 17:36:20 UTC, H. S. Teoh wrote:
>
> Yeah, I think having expression syntax will make contracts more readable.  We'll just have to see.
>

Sorry, but I fail to see how (1) is more readable than (2)

(1)
in(s.length > 0, "s must not be empty")

(2)
in { assert(s.length > 0, "s must not be empty"); }


In (1) The assert .. is removed.
In (1) The scope indicators {} .. are removed.
In (1) The semicolon..is removed.

Removing all these things equates to being more readable??

Sure, it makes it more concise, but more readable??

I assert that it does not. But now..do I use the assert keyword.. or not? Do I end with semicolon..or not??

This just removes things that are still needed elsewhere in your code, but now... you have to remember that sometimes you need those things, and sometimes you don't.

Better to have consistency over conciseness

so glad to hear that existing syntax will remain.
(well, till someone decides that needs to go too)
April 10, 2018
On Wednesday, April 11, 2018 05:23:58 really? via Digitalmars-d-announce wrote:
> On Friday, 6 April 2018 at 17:36:20 UTC, H. S. Teoh wrote:
> > Yeah, I think having expression syntax will make contracts more readable.  We'll just have to see.
>
> Sorry, but I fail to see how (1) is more readable than (2)
>
> (1)
> in(s.length > 0, "s must not be empty")
>
> (2)
> in { assert(s.length > 0, "s must not be empty"); }
>
>
> In (1) The assert .. is removed.
> In (1) The scope indicators {} .. are removed.
> In (1) The semicolon..is removed.
>
> Removing all these things equates to being more readable??
>
> Sure, it makes it more concise, but more readable??
>
> I assert that it does not. But now..do I use the assert keyword.. or not? Do I end with semicolon..or not??
>
> This just removes things that are still needed elsewhere in your code, but now... you have to remember that sometimes you need those things, and sometimes you don't.
>
> Better to have consistency over conciseness
>
> so glad to hear that existing syntax will remain.
> (well, till someone decides that needs to go too)

Many have considered the verboseness of contracts to be a major reason to avoid them. The newer syntax will help with that in the cases where all you need is a series of assertions. However, regardless of how anyone feels about the new syntax, there are cases where you need more than just a series of assertions (e.g. you need to declare one or more variables to use in the assertions). The older syntax is required for such cases, and it would make no sense to remove it even if we didn't care about avoiding code breakage. So, if you prefer the older syntax, then feel free to use it, even if the newer syntax will work. You'll be stuck reading the newer syntax in the code of anyone who prefers the newer syntax, so you can't necessarily avoid dealing with it, but you're not going to be forced to switch to the newer syntax if you don't want to.

Personally, I think that new syntax is very straightforward. It may take some getting used to, but it's basically the same syntax as an assertion except that it has a different keyword, and because it's not a statement, it doesn't need a semicolon. It makes sense in its context, and ultimately, I don't think that it's really going to be readability problem.

That being said, I'm probably still not going to bother with contracts simply because I don't see any real benefit over just putting assertions inside the function except in the cases where inheritance is involved. I find it a lot more tolerable than the old syntax, but I still find it to be pointless so long as contracts are the same thing as putting assertions inside the function (except when inheritance is involved). IMHO, for contracts to be worth much outside of the inheritance case, we'd need to do something like make it so that contracts are compiled in based on whether the caller used -release or not rather than whether the callee did. If that were done, then there would be real value in using contracts, and I'd be a lot more excited about the new syntax. As it is, it seems like a nice improvement that's ultimately pointless.

- Jonathan M Davis

April 11, 2018
On Tue, Apr 10, 2018 at 11:43:00PM -0600, Jonathan M Davis via Digitalmars-d-announce wrote: [...]
> IMHO, for contracts to be worth much outside of the inheritance case, we'd need to do something like make it so that contracts are compiled in based on whether the caller used -release or not rather than whether the callee did.

This is what should have been done in the first place, and I'd argue that this is the direction we should be going in. The current implementation of contracts greatly diminish their value, though personally I'd still use them because they convey intent better than just sticking a bunch of asserts at the top of the function body.


> If that were done, then there would be real value in using contracts, and I'd be a lot more excited about the new syntax. As it is, it seems like a nice improvement that's ultimately pointless.
[...]

I consider this as a first step in improving DbC support in D.  The next step is to make it so that in-contracts are enforced on the caller's side rather than the callee's side.  IIRC, the original version of this DIP included something to this effect, but it was eventually taken off in order to stay more focused in scope so that the chances of acceptance would be higher.  But I hope that eventually a future DIP would address this more fundamental and important issue.


T

-- 
Shin: (n.) A device for finding furniture in the dark.
April 11, 2018
On Wed, Apr 11, 2018 at 05:23:58AM +0000, really? via Digitalmars-d-announce wrote:
> On Friday, 6 April 2018 at 17:36:20 UTC, H. S. Teoh wrote:
> > 
> > Yeah, I think having expression syntax will make contracts more readable.  We'll just have to see.
> > 
> 
> Sorry, but I fail to see how (1) is more readable than (2)
> 
> (1)
> in(s.length > 0, "s must not be empty")
> 
> (2)
> in { assert(s.length > 0, "s must not be empty"); }
> 
> 
> In (1) The assert .. is removed.
> In (1) The scope indicators {} .. are removed.
> In (1) The semicolon..is removed.
> 
> Removing all these things equates to being more readable??
> 
> Sure, it makes it more concise, but more readable??

Yes, because it removes unnecessary syntactical noise from the line. All of that verbose baggage -- braces, "assert", semicolons, is just needless syntactic boilerplate that's repeated verbatim every single time you write a contract, and all for what? Just to express a contract consisting of a single, simple expression.

Besides, the `keyword(expression)` syntax has precedence in signature
constraints:

	auto myFunc(Args)(Args...)
	if (Args.length == 2)	// <---
	...

So now to add a contract:

	auto myFunc(Args)(Args...)
	if (Args.length == 2)
	in (Args[0] < 100)	// consistent with sig constraint syntax
	...


> I assert that it does not. But now..do I use the assert keyword.. or not? Do I end with semicolon..or not??
> 
> This just removes things that are still needed elsewhere in your code, but now... you have to remember that sometimes you need those things, and sometimes you don't.
[...]

It's no different from needing to "remember" that the condition of an if-statement does not require {} and semicolons.  According to your logic, for consistency's sake we should start writing if-statements like this instead:

	if {
		assert(myCondition == true);
		assert(myOtherCondition == false);
	} then {
		...
	}

I wouldn't say it's less readable, but again, needless boilerplate.  If you love so much boilerplate, perhaps Java may be a better language for you.


T

-- 
Lottery: tax on the stupid. -- Slashdotter
April 11, 2018
On Wednesday, April 11, 2018 07:47:14 H. S. Teoh via Digitalmars-d-announce wrote:
> On Tue, Apr 10, 2018 at 11:43:00PM -0600, Jonathan M Davis via Digitalmars-d-announce wrote: [...]
>
> > IMHO, for contracts to be worth much outside of the inheritance case, we'd need to do something like make it so that contracts are compiled in based on whether the caller used -release or not rather than whether the callee did.
>
> This is what should have been done in the first place, and I'd argue that this is the direction we should be going in. The current implementation of contracts greatly diminish their value, though personally I'd still use them because they convey intent better than just sticking a bunch of asserts at the top of the function body.
>
> > If that were done, then there would be real value in using contracts, and I'd be a lot more excited about the new syntax. As it is, it seems like a nice improvement that's ultimately pointless.
>
> [...]
>
> I consider this as a first step in improving DbC support in D.  The next step is to make it so that in-contracts are enforced on the caller's side rather than the callee's side.  IIRC, the original version of this DIP included something to this effect, but it was eventually taken off in order to stay more focused in scope so that the chances of acceptance would be higher.  But I hope that eventually a future DIP would address this more fundamental and important issue.

If we actually end up with a language improvement that makes it so that contracts are compiled in based on the caller instead of the callee, then I'll start using contracts. Until then, I'm not generally going to bother.

And that reminds me, I was considering putting together a DIP to fix the situation with invariants and void initialization. Thanks to the fact that opAssign checks the state of the object prior to assigning it, you basically can't use invariants with anything that you would void initialize, which means that I basically never use invariants, and unlike in and out contracts, invariants are actually a huge boon when they're appropriate, since they insert checks with _every_ public function call, which would be a royal pain to do by hand. Because of this issue, I'd previously argued that opAssign should not check the state of the object before assigning it, but Walter rejected that, and in rare cases, you actually do care about the state of the object before assigning it, so that makes some sense, but it's a huge problem when void initialization gets involved. So, I was thinking that maybe we should have a way to indicate at the call site that an assignment should not call the invariant prior to calling opAssign in that specific case. But I haven't gotten much past that in figuring it out, since it's not all that high on my priority list. It's really annoying if you use invariants, but my solution has been to just not use them, so it's a problem but not one that actively gets in my way at the moment. It's just that I then lose out on invariants. :|

- Jonathan M Davis

April 11, 2018
On Wednesday, 11 April 2018 at 16:16:33 UTC, Jonathan M Davis wrote:
> If we actually end up with a language improvement that makes it so that contracts are compiled in based on the caller instead of the callee, then I'll start using contracts. Until then, I'm not generally going to bother.

My first proposal suggested allowing the contracts at the top of the function body. If you mixed that idea with what H.S. Teoh later proposed, the result would have looked like:

int fun(int a) {
   in(a >= 0);
   out(r; r > 0);
   ...
}

It's not much different from if you did:

int fun(int a) {
   assert(a >= 0);
   typeof(return) result;
   scope(success) assert(result > 0);
   ...use `result`...
}

For anyone who wants even more convenience in how to write contracts this idea would still possible to add, although it's probably not that important.

But that idea received criticism on principle, that contracts are part of the signature and not the body. I didn't much care about the criticism myself, because I just wanted the contracts to be as ergonomic as possible so that people would use them. They seemed like a feature of D whose syntax was not up to the same standards as the rest of D, whose syntax otherwise is a major selling point.

However, eventually I was convinced that the accepted proposal is better precisely because of the possibility of a future implementation where the caller checks rather than the callee. In this case the contracts *must* be in the signature, because the body could be missing altogether. So basically, I agree with H.S. Teoh. A future DIP which allows caller-side checking will be all about the implementation, rather than about the syntax, and may or may not face opposition precisely for that reason, I don't know. From the user's point of view it amounts to nothing more than being able to use contracts in more places, i.e. in precompiled code, and with better error messages that fault the caller instead of the callee. I don't feel technically qualified to write that DIP, but I'm glad that the current DIP is designed with that one in mind.