www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - DIP 1009 (Add Expression-Based Contract Syntax) Accepted

reply Mike Parker <aldacron gmail.com> writes:
Congratulations to Zach Tollen and everyone who worked on DIP 
1009. It took a painful amount of time to get it through the 
process, but it had finally come out of the other side with an 
approval. The proposal itself was approved early on, but it 
needed quite a bit of revision to get to an acceptable final 
draft. The DIP in its final form:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md

Though I will not retroactively apply review summaries to all 
previously approved DIPs, I will do so with those currently 
working through the process. I've started with this one. Note 
that I kept the 'Preliminary Review' name instead of using the 
new 'Community Review' so that it would match the review thread 
title.

I would like to remind everyone that DIP 1013, "The Deprecation 
Process", is currently under Community Review, with very little 
feedback so far. I encourage everyone to take a look at it and 
speak up if any flaws or potential enhancements are seen.

https://forum.dlang.org/thread/rxlbdijkbhanwvbksuej forum.dlang.org
Apr 06
next sibling parent Martin Tschierschke <mt smartdolphin.de> writes:
On Friday, 6 April 2018 at 12:26:36 UTC, Mike Parker wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 
 1009. It took a painful amount of time to get it through the 
 process, but it had finally come out of the other side with an 
 approval. The proposal itself was approved early on, but it 
 needed quite a bit of revision to get to an acceptable final 
 draft. The DIP in its final form:


 https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md
It looks very well designed! And makes using of in/out contracts very pleasant and clear. Thank you to everyone who worked on this DIP!
Apr 06
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Apr 06, 2018 at 12:26:36PM +0000, Mike Parker via
Digitalmars-d-announce wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 1009. It
 took a painful amount of time to get it through the process, but it
 had finally come out of the other side with an approval.
WOOHOO!!!! Just this week, I've started to wonder whatever happened to this DIP. So happy to hear it's approved!! Finally, sane contract syntax! T -- The computer is only a tool. Unfortunately, so is the user. -- Armaphine, K5
Apr 06
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, April 06, 2018 08:00:42 H. S. Teoh via Digitalmars-d-announce 
wrote:
 On Fri, Apr 06, 2018 at 12:26:36PM +0000, Mike Parker via Digitalmars-d-
announce wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 1009. It
 took a painful amount of time to get it through the process, but it
 had finally come out of the other side with an approval.
WOOHOO!!!! Just this week, I've started to wonder whatever happened to this DIP. So happy to hear it's approved!! Finally, sane contract syntax!
It definitely improves the syntax, but I confess that I still don't see much point in using contracts outside of virtual functions. Everywhere else, the behavior is the same if you just put assertions at the top of the function. Now, if the contracts ended up in the documentation or something - or if it were actually changed so that contracts were compiled in based on how the caller were compiled rather than the callee - then maybe having an actual contract would make sense, but as it stands, I don't see the point. - Jonathan M Davis
Apr 06
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Apr 06
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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 -- GEEK = Gatherer of Extremely Enlightening Knowledge
Apr 06
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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.
Apr 06
parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Apr 09
prev sibling parent reply really? <whomever whatever.com> writes:
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)
Apr 10
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Apr 10
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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.
Apr 11
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
Apr 11
prev sibling next sibling parent reply Zach Tollen <reachzach gggmail.com> writes:
On Friday, 6 April 2018 at 12:26:36 UTC, Mike Parker wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 
 1009.
Thanks. People reading the announcement should know that this DIP was almost completely the result of a team effort. My original draft was subject to significant and valid criticism, and in the ensuing forum discussion, the participants collectively revised the entire proposal, using an idea by H.S. Teoh. Then, in rewriting the DIP, both Mike Parker and Timon Gehr were indispensable in meeting the writing standards required for a highly technical DIP. If the process permitted giving the latter two credit as DIP authors (which it didn't!), I would readily have done so without hesitation. Thank you both. 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! - Zach
Apr 06
parent reply Jordan Wilson <wilsonjord gmail.com> writes:
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
Apr 07
parent Zach Tollen <reachzach gggmail.com> writes:
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.
Apr 07
prev sibling next sibling parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Friday, 6 April 2018 at 12:26:36 UTC, Mike Parker wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 
 1009. It took a painful amount of time to get it through the 
 process, but it had finally come out of the other side with an 
 approval. The proposal itself was approved early on, but it 
 needed quite a bit of revision to get to an acceptable final 
 draft. The DIP in its final form:


 https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md
Great work. Great syntax.
Apr 06
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2018-04-06 14:26, Mike Parker wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 1009. It 
 took a painful amount of time to get it through the process, but it had 
 finally come out of the other side with an approval. The proposal itself 
 was approved early on, but it needed quite a bit of revision to get to 
 an acceptable final draft. The DIP in its final form:
 
 
 https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md
 
 Though I will not retroactively apply review summaries to all previously 
 approved DIPs, I will do so with those currently working through the 
 process. I've started with this one. Note that I kept the 'Preliminary 
 Review' name instead of using the new 'Community Review' so that it 
 would match the review thread title.
 
 I would like to remind everyone that DIP 1013, "The Deprecation 
 Process", is currently under Community Review, with very little feedback 
 so far. I encourage everyone to take a look at it and speak up if any 
 flaws or potential enhancements are seen.
 
 https://forum.dlang.org/thread/rxlbdijkbhanwvbksuej forum.dlang.org
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. When a DIP is accepted and it contains multiple alternatives, can we move the non-accepted alternatives to a separate section, use a strike through font style or similar? [1] https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md#new-out-syntax -- /Jacob Carlborg
Apr 07
parent Zach Tollen <reachzach gggmail.com> writes:
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.
Apr 09
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Apr 11
parent Zach Tollen <reachzach gggmail.com> writes:
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.
Apr 11
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On Friday, 6 April 2018 at 12:26:36 UTC, Mike Parker wrote:
 Congratulations to Zach Tollen and everyone who worked on DIP 
 1009. It took a painful amount of time to get it through the 
 process, but it had finally come out of the other side with an 
 approval. The proposal itself was approved early on, but it 
 needed quite a bit of revision to get to an acceptable final 
 draft. The DIP in its final form:


 https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md
What would have made contract trully powerful for me is them being emitted at caller side. This way if I use a release build of library but debugging my app I still get my stupidity guarded by contracts of the API. * Now *that* would be marvelous. Otherwise having a debug build for each of libraries just to check my precondition is too much of drag I’d say. After all libraries are typically stable code that are (presumably) debugged and you want them to be fast. * Templates kind of muddy the waters being conpiled with the flags of caller (another reason why they are a mess). Meaning they will work with contracts if caller choses to have debug build.
Apr 11
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Apr 11, 2018 at 08:45:15PM +0000, Dmitry Olshansky via
Digitalmars-d-announce wrote:
[...]
 What would have made contract trully powerful for me is them being
 emitted at caller side. This way if I use a release build of library
 but debugging my app I still get my stupidity guarded by contracts of
 the API. *
[...] I say this should be the next step. We should write up a DIP for this. T -- Creativity is not an excuse for sloppiness.
Apr 11
prev sibling parent reply Kagamin <spam here.lot> writes:
On Wednesday, 11 April 2018 at 20:45:15 UTC, Dmitry Olshansky 
wrote:
 * Templates kind of muddy the waters being conpiled with the 
 flags of caller (another reason why they are a mess). Meaning 
 they will work with contracts if caller choses to have debug 
 build.
Template can call user code, but it wasn't tested for it, so the contract should be checked.
Apr 11
parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On Thursday, 12 April 2018 at 06:08:39 UTC, Kagamin wrote:
 On Wednesday, 11 April 2018 at 20:45:15 UTC, Dmitry Olshansky 
 wrote:
 * Templates kind of muddy the waters being conpiled with the 
 flags of caller (another reason why they are a mess). Meaning 
 they will work with contracts if caller choses to have debug 
 build.
Template can call user code, but it wasn't tested for it, so the contract should be checked.
What I mean is that for templates calling or not calling contracts depends on client code not the library. It’s just one consequence of template mechanism that has tons of other issues.
Apr 12