www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP 1009--Improve Contract Usability--Preliminary Review Round 2

reply Mike Parker <aldacron gmail.com> writes:
DIP 1009 is titled "Improve Contract Usability".

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

Based on feedback from the first round, this DIP has been revised 
to the extent that a second preliminary review round is warranted.

All review-related feedback on and discussion of the DIP should 
occur in this thread. The review period will end at 11:59 PM ET 
on August 4 (3:59 AM GMT August 5), or when I make a post 
declaring it complete.

At the end of Round 2, if further review is deemed necessary, the 
DIP will be scheduled for another round. Otherwise, it will be 
queued for the formal review and evaluation by the language 
authors.

Thanks in advance to all who participate.

Destroy!
Jul 21
next sibling parent Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".
I like it. I would prefer the out with two sets of parantheses.
Jul 21
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 21.07.2017 15:51, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".
 
 https://github.com/dlang/DIPs/blob/master/DIPs/DIP1009.md
 
 Based on feedback from the first round, this DIP has been revised to the 
 extent that a second preliminary review round is warranted.
 
 All review-related feedback on and discussion of the DIP should occur in 
 this thread. The review period will end at 11:59 PM ET on August 4 (3:59 
 AM GMT August 5), or when I make a post declaring it complete.
 
 At the end of Round 2, if further review is deemed necessary, the DIP 
 will be scheduled for another round. Otherwise, it will be queued for 
 the formal review and evaluation by the language authors.
 
 Thanks in advance to all who participate.
 
 Destroy!
"in and out expressions must come at the end of the function declarator suffix, and before the regular contracts, if any" The implementation actually allows all possible notations for contracts to be mixed freely. Whether or not 'do' is required depends on what notation is used by the last contract.
Jul 21
parent MysticZach <reachzach ggmail.com> writes:
On Friday, 21 July 2017 at 15:13:09 UTC, Timon Gehr wrote:
 "in and out expressions must come at the end of the function 
 declarator suffix, and before the regular contracts, if any"

 The implementation actually allows all possible notations for 
 contracts to be mixed freely. Whether or not 'do' is required 
 depends on what notation is used by the last contract.
I decided that for grammar purposes it would be easier to require the contract expressions before the contract blocks. Contract blocks are currently conflated grammatically with FunctionBody [1]. An accurate grammar that describes the current implementation would be twice as complicated, because FunctionBody would have to be redefined. I want the feature to be as simple as possible to understand, so I didn't think it was worth it. There has also been mention of the possibility of improving the implementation of contracts to allow separate compilation, in which case the signature, plus contracts, could some day appear without the body. I wanted to define the new expressions to accommodate this possibility. [1] https://dlang.org/spec/grammar.html#FunctionBody
Jul 21
prev sibling next sibling parent reply David Gileadi <gileadisNOSPM gmail.com> writes:
On 7/21/17 6:51 AM, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".
For out contracts that use the return identifier, could the keyword "return" be used? out(return > 0) One possible problem with this syntax is a future where functions could have multiple return values...
Jul 21
parent reply Moritz Maxeiner <moritz ucworks.org> writes:
On Friday, 21 July 2017 at 18:35:53 UTC, David Gileadi wrote:
 On 7/21/17 6:51 AM, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".
For out contracts that use the return identifier, could the keyword "return" be used? out(return > 0) One possible problem with this syntax is a future where functions could have multiple return values...
No, see Round 1 discussion [1] [1] http://forum.dlang.org/post/oihbot$134s$1 digitalmars.com
Jul 21
parent David Gileadi <gileadisNOSPM gmail.com> writes:
On 7/21/17 11:41 AM, Moritz Maxeiner wrote:
 On Friday, 21 July 2017 at 18:35:53 UTC, David Gileadi wrote:
 On 7/21/17 6:51 AM, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".
For out contracts that use the return identifier, could the keyword "return" be used? out(return > 0) One possible problem with this syntax is a future where functions could have multiple return values...
No, see Round 1 discussion [1] [1] http://forum.dlang.org/post/oihbot$134s$1 digitalmars.com
Ah, thanks--I missed that.
Jul 21
prev sibling next sibling parent reply Moritz Maxeiner <moritz ucworks.org> writes:
On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".

 [...]

 Destroy!
I really like how the syntax turned out. My only remaining peeve is the `ContractParameters` nomenclature in the grammar section, because it implies that asserts are contracts. If contracts and asserts share a common grammar rule, imho the rule's name should be agnostic to either of them, like `ConditionalParameters`. In any case, it's a complaint on a very high level and arguably not relevant to any end user (as usually no one other than compiler people look at the grammar rules, anyway). Thanks for the time invested in the DIP!
Jul 21
parent reply MysticZach <reachzach ggmail.com> writes:
On Friday, 21 July 2017 at 18:55:08 UTC, Moritz Maxeiner wrote:

 I really like how the syntax turned out. My only remaining 
 peeve is the `ContractParameters` nomenclature in the grammar 
 section, because it implies that asserts are contracts.
Maybe I should have stuck with AssertParameters. That can easily be fixed.
Jul 21
parent Moritz Maxeiner <moritz ucworks.org> writes:
On Friday, 21 July 2017 at 19:19:47 UTC, MysticZach wrote:
 On Friday, 21 July 2017 at 18:55:08 UTC, Moritz Maxeiner wrote:

 I really like how the syntax turned out. My only remaining 
 peeve is the `ContractParameters` nomenclature in the grammar 
 section, because it implies that asserts are contracts.
Maybe I should have stuck with AssertParameters. That can easily be fixed.
I know this is being pedantic to an annoying degree (sorry), but that would just invert the implication's direction, i.e. "it implies that contracts are asserts". The only way I can think of right now to get rid of the implication would be to choose a name that is agnostic to either of them.
Jul 21
prev sibling next sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Jul 21, 2017 at 01:51:05PM +0000, Mike Parker via Digitalmars-d wrote:
 DIP 1009 is titled "Improve Contract Usability".
 
 https://github.com/dlang/DIPs/blob/master/DIPs/DIP1009.md
[...] As far as the meat of the proposal is concerned, I like it. The syntax of the out-contract without an identifier `out(;...)` is unfortunate, but understandable because otherwise it will cause an ambiguity with the existing verbose syntax that we will continue to support. However, I think the presentation of the DIP needs some work. For example, the rationales and lines of reasoning that eventually led to the currently proposed syntax, both from the original draft of this DIP and from the ensuing discussion in the previous review thread, ought to be included (of course, in summarized form -- no need to repeat the back-and-forth of the original discussions, but just the eventual line of thought). If possible, some of the discarded alternatives could be mentioned along with the reasons why they were eventually decided against. In short, I feel that a more substantial discussion of how we arrived at the current form of the proposal is important so that Walter & Andrei can have the adequate context to appreciate the proposed syntax changes, and not feel like this is just one possibility out of many others that haven't been adequately considered. Also, I think some discussion of how the new syntax will interact with the existing one is warranted: for example, recommendations as to when to use the new syntax, and when to revert to the old (if it's a one-line contract, use the new syntax; if you need to write a for-loop in your contract, the old syntax is still available, etc.). This will also help to give W&A a better idea of how this proposal will fit in with the current syntax. And there should be at least one example of a body-less function declaration with contracts, just to see what it looks like in that case. T -- Too many people have open minds but closed eyes.
Jul 21
next sibling parent Mike Parker <aldacron gmail.com> writes:
On Friday, 21 July 2017 at 19:36:08 UTC, H. S. Teoh wrote:

 However, I think the presentation of the DIP needs some work. 
 For example, the rationales and lines of reasoning that 
 eventually led to the currently proposed syntax, both from the 
 original draft of this DIP and from the ensuing discussion in 
 the previous review thread, ought to be included (of course, in 
 summarized form -- no need to repeat the back-and-forth of the 
 original discussions, but just the eventual line of thought). 
 If possible, some of the discarded alternatives could be 
 mentioned along with the reasons why they were eventually 
 decided against.
All of the relevant information is available. The previous version of the DIP is in a link in the header (the 'Most Recent' link in the Review Count section) and links to all previous reviews can always be found in the Reviews section at the bottom. My view is that the current version of a DIP at each stage of the process should be pristine, as if it were written specifically for that stage. The problem I have with summarizing what came before is not everyone will agree what is the most important bits to add to the summary, and its very presence will make it easy to avoid reading previous drafts in their entirety. Much better, IMO, to just include the links and let readers decide for themselves what is important.
Jul 21
prev sibling next sibling parent reply MysticZach <reachzach ggmail.com> writes:
On Friday, 21 July 2017 at 19:36:08 UTC, H. S. Teoh wrote:
 In short, I feel that a more substantial discussion of how we 
 arrived at the current form of the proposal is important so 
 that Walter & Andrei can have the adequate context to 
 appreciate the proposed syntax changes, and not feel like this 
 is just one possibility out of many others that haven't been 
 adequately considered.
I think we have to assume they've been reading the prior threads. If they have specific questions or concerns, then we have to hope they'll express them here, rather than just reject the proposal. I'll put you in the author line as a co-author if you want, as this _is_ essentially your proposal.
 And there should be at least one example of a body-less 
 function declaration with contracts, just to see what it looks 
 like in that case.
Right now, such declarations are only legal in interfaces. That might change if the implementation changes. Here's how one would look with the new syntax: interface I { void fun(int a) in(a); }
Jul 21
parent reply Olivier FAURE <olivier.faure epitech.eu> writes:
On Saturday, 22 July 2017 at 04:48:34 UTC, MysticZach wrote:
 On Friday, 21 July 2017 at 19:36:08 UTC, H. S. Teoh wrote:
 In short, I feel that a more substantial discussion of how we 
 arrived at the current form of the proposal is important so 
 that Walter & Andrei can have the adequate context to 
 appreciate the proposed syntax changes, and not feel like this 
 is just one possibility out of many others that haven't been 
 adequately considered.
I think we have to assume they've been reading the prior threads. If they have specific questions or concerns, then we have to hope they'll express them here, rather than just reject the proposal. I'll put you in the author line as a co-author if you want, as this _is_ essentially your proposal.
I feel like making a list of alternative proposals and why they were rejected would still be a good idea, both to improve the quality of the debate in this thread (people are proposing alternative syntaxes that should be addressed in the DIP), and for posterity.
Jul 25
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 25 July 2017 at 07:58:13 UTC, Olivier FAURE wrote:
 I feel like making a list of alternative proposals and why they 
 were rejected would still be a good idea, both to improve the 
 quality of the debate in this thread (people are proposing 
 alternative syntaxes that should be addressed in the DIP), and 
 for posterity.
We weren't speaking of rejected proposals, but of previously reviewed drafts. Rejected proposals already include a summary of why they were rejected. You can a list of all DIPs submitted under the current process, including links and their current status, at: https://github.com/dlang/DIPs/blob/master/DIPs/README.md And please everyone, I'm happy to discuss ideas to improve the DIP process, but let's not do it in the review threads. Email me, start a new thread, whatever, but please try to keep review threads on the topic at hand. Thanks!
Jul 25
parent reply Olivier FAURE <olivier.faure epitech.eu> writes:
On Tuesday, 25 July 2017 at 09:53:02 UTC, Mike Parker wrote:
 On Tuesday, 25 July 2017 at 07:58:13 UTC, Olivier FAURE wrote:
 I feel like making a list of alternative proposals and why 
 they were rejected would still be a good idea, both to improve 
 the quality of the debate in this thread (people are proposing 
 alternative syntaxes that should be addressed in the DIP), and 
 for posterity.
We weren't speaking of rejected proposals, but of previously reviewed drafts. Rejected proposals already include a summary of why they were rejected. You can a list of all DIPs submitted under the current process, including links and their current status, at: https://github.com/dlang/DIPs/blob/master/DIPs/README.md
I... think you misunderstood me? I shouldn't have used the word 'proposals', I should have said 'suggestions'. What I meant was "I think it would be better for the current version of DIP 1009 to include a 'Rejected alternative syntaxes' that would include a summary of the previously discussed suggestions for improving contract readability." MysticZach argues that such a section would be pointless since the language authors read the previous version of DIP 1009, but I still think adding it would be a good idea (for posterity and to streamline discussions in this thread).
Jul 26
parent MysticZach <reachzach ggmail.com> writes:
On Wednesday, 26 July 2017 at 08:12:39 UTC, Olivier FAURE wrote:
 I... think you misunderstood me? I shouldn't have used the word 
 'proposals', I should have said 'suggestions'.

 What I meant was "I think it would be better for the current 
 version of DIP 1009 to include a 'Rejected alternative 
 syntaxes' that would include a summary of the previously 
 discussed suggestions for improving contract readability."

 MysticZach argues that such a section would be pointless since 
 the language authors read the previous version of DIP 1009, but 
 I still think adding it would be a good idea (for posterity and 
 to streamline discussions in this thread).
I don't know. DIPs have both a forward-looking and a backward-looking aspect. The forward is to convince the language authors of the need/value of a specific language change. The backward is to record a history of discussions so that people can learn why things are the way they are. They are both valuable in their own way, but I think the forward-looking aspect is more valuable. I'd like some guidance from the leadership as to the important of the backward-looking aspect of DIPs. For example, DIP1003 was actually rewritten to excise the alternatives and keep only the one adopted. The motive given was that people looking for the history could examine prior versions of the DIP. I guess the motive is that too much history can end up cluttering the important information. That said, I think that making good decisions for the language far outweighs any concerns about DIPs themselves. So we should really be focusing on that.
Jul 26
prev sibling parent MysticZach <reachzach ggmail.com> writes:
On Friday, 21 July 2017 at 19:36:08 UTC, H. S. Teoh wrote:
 However, I think the presentation of the DIP needs some work. 
 For example, the rationales and lines of reasoning that 
 eventually led to the currently proposed syntax, both from the 
 original draft of this DIP and from the ensuing discussion in 
 the previous review thread, ought to be included (of course, in 
 summarized form -- no need to repeat the back-and-forth of the 
 original discussions, but just the eventual line of thought). 
 If possible, some of the discarded alternatives could be 
 mentioned along with the reasons why they were eventually 
 decided against.
The first draft of the current proposal actually started with this approach: https://github.com/dlang/DIPs/commit/677c4e2bd5ff9b4bcbca35a28831560d5ce06f8c Hopefully this will help: https://github.com/dlang/DIPs/pull/88
Jul 22
prev sibling next sibling parent reply aberba <karabutaworld gmail.com> writes:
On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".

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

 Based on feedback from the first round, this DIP has been 
 revised to the extent that a second preliminary review round is 
 warranted.

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on August 4 (3:59 AM GMT August 5), or when I make a post 
 declaring it complete.

 At the end of Round 2, if further review is deemed necessary, 
 the DIP will be scheduled for another round. Otherwise, it will 
 be queued for the formal review and evaluation by the language 
 authors.

 Thanks in advance to all who participate.

 Destroy!
How about this in current syntax? (that's what I do) int func(int a) in { assert(a >= 0); } out(result) { assert(result >= 2); } body { return 2 * a; } an improvement could be: int func(int a) in assert(a >= 0); out(result) assert(result >= 2); body { return 2 * a; } just like an in-line if-else statement
Jul 21
next sibling parent MysticZach <reachzach ggmail.com> writes:
On Saturday, 22 July 2017 at 03:05:55 UTC, aberba wrote:
 How about this in current syntax? (that's what I do)

 int func(int a)
     in
     {
         assert(a >= 0);
     }
     out(result)
     {
         assert(result >= 2);
     }
 body
 {
     return 2 * a;
 }


 an improvement could be:

 int func(int a)
     in assert(a >= 0);
     out(result) assert(result >= 2);
 body
 {
     return 2 * a;
 }

 just like an in-line if-else statement
That was actually part of my original proposal [1]. People in that discussion [2] seemed more excited about the current proposal , and they won me over to it. If the syntax doesn't assume `assert`, probably 99% of contracts will use it explicitly, so it's really making it easier by just assuming it. And being allowed to omit the word `body` (now `do`) with the new syntax is an important feature. That said, I don't think your proposal is incompatible with the current one. It just might be made unnecessary by it. [1] https://github.com/dlang/DIPs/blob/d2dc77802c74378cf4545069eced21f85fbf893f/DIPs/DIP1009.md [2] http://forum.dlang.org/post/gjtsfysvtyxcfcmuutez forum.dlang.org
Jul 21
prev sibling parent Moritz Maxeiner <moritz ucworks.org> writes:
On Saturday, 22 July 2017 at 03:05:55 UTC, aberba wrote:
 How about this in current syntax? (that's what I do)

 int func(int a)
     in
     {
         assert(a >= 0);
     }
     out(result)
     {
         assert(result >= 2);
     }
 body
 {
     return 2 * a;
 }
I can only restate my opinion against the above as "too verbose" for the common use case of simple conditions such as null pointer, range empty, etc. Until in contracts are injected at the call site, the above is essentially equivalent to this less verbose version: --- int func(int a) { assert (a >= 0); // > should be used here, though int result; scope (success) assert (result >= 2); return result = 2*a; } ---
 an improvement could be:

 int func(int a)
     in assert(a >= 0);
     out(result) assert(result >= 2);
 body
 {
     return 2 * a;
 }

 just like an in-line if-else statement
Summary of issues with that (that you can also find in the Round 1 discussion): - Free semicolons within the function signature are inconsistent with the rest of D - The `body` keyword is redundant here; imho it should also have been removed (deprecation first) from the current contract syntax instead of being replaced by `do`, because it's inconsistent with the rest of D to require a keyword to delimit the *end* of an optional element, but since those (shell) contracts are extremely verbose, anyway, it doesn't matter much - There already is the verbose syntax to specify contracts as "shells" that are to be explicitly filled with whatever checks one needs (assert, enforce, etc.), i.e. requiring the user to couple a contract with its implementation; the new syntax allows the user to specify contracts as what they originally are (in the DbC context): abstract promises between caller and callee with the user not needing to worry about the implementation. - Imho the reason why current contract syntax is used only by few people is its verbosity; the more succinct the new syntax, the higher chance I think it has of yielding more widespread use
Jul 22
prev sibling next sibling parent reply Andrea Fontana <nospam example.com> writes:
On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".

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

 Based on feedback from the first round, this DIP has been 
 revised to the extent that a second preliminary review round is 
 warranted.

 All review-related feedback on and discussion of the DIP should 
 occur in this thread. The review period will end at 11:59 PM ET 
 on August 4 (3:59 AM GMT August 5), or when I make a post 
 declaring it complete.

 At the end of Round 2, if further review is deemed necessary, 
 the DIP will be scheduled for another round. Otherwise, it will 
 be queued for the formal review and evaluation by the language 
 authors.

 Thanks in advance to all who participate.

 Destroy!
I don't like it so much but also something like this could be considered: out!(x => x>0) or maybe: out!x(x > 0) that can't collide with current syntax Andrea
Jul 25
next sibling parent Moritz Maxeiner <moritz ucworks.org> writes:
On Tuesday, 25 July 2017 at 07:48:39 UTC, Andrea Fontana wrote:
 On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".

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

 Based on feedback from the first round, this DIP has been 
 revised to the extent that a second preliminary review round 
 is warranted.

 All review-related feedback on and discussion of the DIP 
 should occur in this thread. The review period will end at 
 11:59 PM ET on August 4 (3:59 AM GMT August 5), or when I make 
 a post declaring it complete.

 At the end of Round 2, if further review is deemed necessary, 
 the DIP will be scheduled for another round. Otherwise, it 
 will be queued for the formal review and evaluation by the 
 language authors.

 Thanks in advance to all who participate.

 Destroy!
I don't like it so much but also something like this could be considered: out!(x => x>0) or maybe: out!x(x > 0)
W.r.t. `out!`: With `Identifier !` for template instantiations `Keyword !` would effectively make two things that look the same be completely different. W.r.t. `=>`: See replies to [1] [1] http://forum.dlang.org/post/oio796$k6e$1 digitalmars.com
Jul 25
prev sibling parent MysticZach <reachzach ggmail.com> writes:
On Tuesday, 25 July 2017 at 07:48:39 UTC, Andrea Fontana wrote:
 I don't like it so much but also something like this could be 
 considered:

 out!(x => x>0)
 or maybe:
 out!x(x > 0)

 that can't collide with current syntax

 Andrea
It's another viable option, but it doesn't seem to stand out much from the crowd. Most people, including me, seem to think `out(x; x > 0)` and `out(; y > 0)` are the "least imperfect" option. I suspect they would win if put to a vote. Maybe the leadership can come up with something better. People will get used to whatever is selected. I just like the foreach version because it's simple and concise. I also don't think the ambiguous `out(x > 0)` syntax is that bad for non-return variables. But I can also see why that's suboptimal from a design point of view.
Jul 26
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".

 https://github.com/dlang/DIPs/blob/master/DIPs/DIP1009.md
I think the proposed in/out expression contracts should require pure expressions. In the rare case that impurity is required, the old syntax can be used. This makes the proposal more useful. Otherwise, the expression would have to be awkwardly wrapped in `()pure => expr` code to enforce this (without requiring purity of function body too). It's too late to require purity for existing contract syntax, but we have an opportunity here. One option to solve the out contract ambiguity and aid parsing by tools is to require 'do' after out contract expressions. It allows the syntax `out(expression) do {...}`, even when expression is a single identifier that should be interpreted as a boolean expression.
Jul 28
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 28.07.2017 13:04, Nick Treleaven wrote:
 On Friday, 21 July 2017 at 13:51:05 UTC, Mike Parker wrote:
 DIP 1009 is titled "Improve Contract Usability".

 https://github.com/dlang/DIPs/blob/master/DIPs/DIP1009.md
I think the proposed in/out expression contracts should require pure expressions. In the rare case that impurity is required, the old syntax can be used. This makes the proposal more useful. Otherwise, the expression would have to be awkwardly wrapped in `()pure => expr` code to enforce this (without requiring purity of function body too). It's too late to require purity for existing contract syntax, but we have an opportunity here. ...
No, please. Even the fact that 'out' implicitly applies 'const' is annoying enough, and there is absolutely no good reason to make the two notations behave differently.
Jul 28
prev sibling parent reply MysticZach <reachzach ggmail.com> writes:
On Friday, 28 July 2017 at 11:04:23 UTC, Nick Treleaven wrote:
 One option to solve the out contract ambiguity and aid parsing 
 by tools is to require 'do' after out contract expressions. It 
 allows the syntax `out(expression) do {...}`, even when 
 expression is a single identifier that should be interpreted as 
 a boolean expression.
One of the main goals of this DIP is to eliminate the need for `body/do` in the common case. It would significantly reduce this DIP's value if it couldn't do that, IMO.
Jul 28
next sibling parent reply Moritz Maxeiner <moritz ucworks.org> writes:
On Friday, 28 July 2017 at 16:44:24 UTC, MysticZach wrote:
 On Friday, 28 July 2017 at 11:04:23 UTC, Nick Treleaven wrote:
 One option to solve the out contract ambiguity and aid parsing 
 by tools is to require 'do' after out contract expressions. It 
 allows the syntax `out(expression) do {...}`, even when 
 expression is a single identifier that should be interpreted 
 as a boolean expression.
One of the main goals of this DIP is to eliminate the need for `body/do` in the common case. It would significantly reduce this DIP's value if it couldn't do that, IMO.
This*1000. Having a keyword delimit the end of an optional is both redundant and inconsistent with virtually every other rule in the D grammar (except old contract syntax). It's one of the (two) major reasons why I don't use the original contract syntax.
Jul 28
parent Nick Treleaven <nick geany.org> writes:
On Friday, 28 July 2017 at 16:58:41 UTC, Moritz Maxeiner wrote:
 Having a keyword delimit the end of an optional is both 
 redundant and inconsistent
You are arguing against the current syntax, not my proposal. In my case the `do` keyword would be disambiguating between out expressions and out blocks. It is not redundant, by the same logic I could argue that `;` in `(; identifier)` is redundant. They are different valid options of disambiguation.
Jul 31
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Friday, 28 July 2017 at 16:44:24 UTC, MysticZach wrote:
 On Friday, 28 July 2017 at 11:04:23 UTC, Nick Treleaven wrote:
 One option to solve the out contract ambiguity and aid parsing 
 by tools is to require 'do' after out contract expressions.
BTW `do` would only be required before the {} function body - further `in` and `out` clauses also can be used to disambiguate, see below.
 One of the main goals of this DIP is to eliminate the need for 
 `body/do` in the common case. It would significantly reduce 
 this DIP's value if it couldn't do that, IMO.
This is subjective. If you put `do` on the end of the line, it is trivial: in(x > 4) out(works) out(r; r.test) out(flag) do { // body }
Jul 31
parent MysticZach <reachzach ggmail.com> writes:
On Monday, 31 July 2017 at 09:55:22 UTC, Nick Treleaven wrote:
 This is subjective. If you put `do` on the end of the line, it 
 is trivial:

 in(x > 4)
 out(works)
 out(r; r.test)
 out(flag) do
 {
   // body
 }
The common case is for `out` contracts to test for the return variable. Something like 90% will therefore look like: int fun(int x) out(r; r > 0) { } So it's the uncommon case we're trying to solve for. Requiring `do` in precisely one case, which is the rare case in which the `out` test has only one identifier, and therefore can't be disambiguated from existing `out` contracts, is a solution to that problem. It's seems like a complicated one. To me, it's simpler to simply require the `;` because it's the uncommon case to begin with, and everyone will know what it means because they'll be used to seeing `out(r; r > 0)`. That said, `do` can solve the loophole with the alternative ambiguous syntax. For example: int fun(ref int x, ref int y, ref int z) out(x) // fine, followed by another contract out(y != 0) // fine, multiple tokens, unambiguous out(z) do // fine, followed by `do` { } If you forget to add the `do` there is an inevitable parsing error, so it's not that bad even in the worst case. The error can be fixed by changing `out(z)` to `out(z != 0)`, or to `out(z) do` as you suggest. `do` is only going to be valuable in that one case, though. I'd say it depends where the language designers want to pay the cost of solving the problem. Either pay it up front with the ugliness of the foreach syntax, or pay it in complexity with the different cases of the ambiguous syntax. Because it's a programming language and not a sports car, I'd probably choose the consistency of the foreach syntax over the attractiveness of the ambiguous syntax. But there's no clear winner, IMO.
Aug 01