August 02, 2014
On 8/1/2014 4:03 PM, David Bregman wrote:
> Unfortunately these "detailed rationales" consisted mostly of attacking straw
> men, and some other unsound arguments :(

Of course, we always believe the other side's arguments are of that nature when we find them unconvincing.

To quote my favorite Hamilton Burger line: "irrelevant, immaterial, and incompetent!" is a fair thing to say. But saying "Your honor, he did not present a case" is not fair.


> My last reply to you is still unanswered if you want to give it another try.

I didn't because a reply would just be another cut-and-paste of what I've already posted. I don't have anything new to say.

August 02, 2014
On 08/02/2014 02:18 AM, Walter Bright wrote:
> On 8/1/2014 4:03 PM, David Bregman wrote:
>> Unfortunately these "detailed rationales" consisted mostly of
>> attacking straw
>> men, and some other unsound arguments :(
>
> Of course, we always believe the other side's arguments are of that
> nature when we find them unconvincing.

No. No. No.
August 02, 2014
On 08/02/2014 02:04 AM, H. S. Teoh via Digitalmars-d wrote:
> On Sat, Aug 02, 2014 at 01:59:29AM +0200, Timon Gehr via Digitalmars-d wrote:
>> On 08/02/2014 01:46 AM, H. S. Teoh via Digitalmars-d wrote:
>>> OTOH, perhaps one way to work around this, is to have a function with
>>> an in-contract compile into a preamble and a body:
>>>
>>> 	int func(int x)
>>> 	in { assert(x > 5); }
>>> 	body {
>>> 		return computeResult(x);
>>> 	}
>>>
>>> would compile to the equivalent of:
>>>
>>> 	int __func_incontract(int x) {
>>> 		assert(x > 5);
>>> 		goto __func_body;	// fall through to __func_body
>>> 	}
>>> 	int __func_body(int x) {
>>> 		return computeResult(x);
>>> 	}
>>>
>>> In non-release mode, calls to func would get translated into calls to
>>> __func_incontract,
>>
>> What if a library function was compiled in release mode?
>
> The compiler always emits the in-contract,

I know.

> so the library would carry all the in-contracts.

Indeed.

> If the user code doesn't actually use them, then
> the linker just doesn't link them in at link time.
> ...

I was trying to half-jokingly make a pedantic point about the nature of "the equivalent of: [...] assert(x > 5); [...]" in release mode.

Another issue is that if one just emits the above lowering, the optimizers might not be able to assume the in contract correct on entry of __func__body without further precautions.
August 02, 2014
On Friday, 1 August 2014 at 19:10:34 UTC, Walter Bright wrote:
> On 8/1/2014 6:12 AM, Dicebot wrote:
>> ok, can this be considered a good summary of using assertions/contracts for
>> services where risk of entering undefined state is unacceptable?
>>
>> 1) never use `assert` or contracts in actual application code, use `enforce`
>> instead
>> 2) never use `enforce` in library code unless it does actual I/O, use contracts
>> instead
>> 3) always distribute both release and debug builds of libraries and always run
>> tests in both debug and release mode
>>
>> Does it make sense? Your actual recommendation contradict each other but it is
>> best what I was able to combine them into.
>
> What makes me hesitate about use of enforce() is its high runtime cost. It's not just the computation, but the call stack above it is affected by enforce() being throwable and allocating via the GC.

`enforce` does have overload which allows to use pre-allocated exception instance. Or, alternatively, we may need a similar helper wich does `if (!condition) abort()` with no interaction with -release or optimizer.

Whatever is chosen it does seem that contracts can't be used in application code because it is too affected by user input and is too likely to expose hidden bugs in production.

> Secondly, enforce() is about recoverable errors. Program bugs are simply NOT recoverable errors, and I cannot recommend using them for that purpose. I've argued for decades with people who insist that they can write code that recovers from unknown programming bugs.

1) one can always `enforce` with a pre-allocated Error, will druntime handle that as expected?

2) There is certain class of applications where even programming bugs can (and must be) considered recoverable. Network services that don't yet have full scale high availability infrastructure (and thus can't afford downtime of restarting the app) are quite likely to only terminate connection fibers when programming bug is found - it does not affect serving any other connections. It may be fundamentally wrong but is is pragmatical working approach.

These questions are not theoretical - we regularly have discussion about how contracts may / should be used at work with no clear understanding / agreement so far. I am interested in simple set of guidelines that won't turn writing every single function in a guessing game (does a contract fit here?)
August 02, 2014
On Saturday, 2 August 2014 at 00:18:30 UTC, Walter Bright wrote:
> On 8/1/2014 4:03 PM, David Bregman wrote:
>> Unfortunately these "detailed rationales" consisted mostly of attacking straw
>> men, and some other unsound arguments :(
> Of course, we always believe the other side's arguments are of that nature when we find them unconvincing.
>

Actually I find most unconvincing arguments originate from different axioms/values or different subjective evaluations of tradeoffs, rather than unsound logic. Inability to reach agreement on purely logical argument such as equivalence/non-equivalence of two concepts is pretty rare in this kind of setting (tech discussion between people trained in logic). Frankly I'm kinda shocked that this hasn't been resolved yet after so much back and forth.

> To quote my favorite Hamilton Burger line: "irrelevant, immaterial, and incompetent!" is a fair thing to say. But saying "Your honor, he did not present a case" is not fair.
>
>
>> My last reply to you is still unanswered if you want to give it another try.
>
> I didn't because a reply would just be another cut-and-paste of what I've already posted. I don't have anything new to say.

OK, I think I have an idea how to be more convincing (I wish I'd thought of this earlier):

is this
http://www.cplusplus.com/reference/cassert/assert/

the same as this?
http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx

can you see the difference now?
August 02, 2014
Am 02.08.2014 04:13, schrieb David Bregman:
>
> is this
> http://www.cplusplus.com/reference/cassert/assert/
>
> the same as this?
> http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx
>
> can you see the difference now?

Oh, interesting quote from the __assume() link:
"Use __assume in an ASSERT only when the assert is not recoverable. Do not use __assume in an assert for which you have subsequent error recovery code because the compiler might optimize away the error-handling code."

So maybe it's not so unusual to handle an error that is checked with assert() after all.

Cheers,
Daniel
August 02, 2014
On 8/1/2014 7:13 PM, David Bregman wrote:
> OK, I think I have an idea how to be more convincing (I wish I'd thought of this
> earlier):
>
> is this
> http://www.cplusplus.com/reference/cassert/assert/
>
> the same as this?
> http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx
>
> can you see the difference now?

What I see is Microsoft attempting to bring D's assert semantics into C++. :-)

As I've mentioned before, there is inexorable pressure for this to happen, and it will happen.
August 02, 2014
On Friday, 1 August 2014 at 20:22:39 UTC, Tofu Ninja wrote:
> On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote:
>
>> Yes, but is the same for the C apps. There, you have no assertion in the release build, the release build is optimized (I imagine very few would use -O0 on it...), then the sefault happens.
>>
>
> In c the assert is just a check, no assume, the Microsoft compiler even has its own __assume separate from assert.

Because the assert is in the library, not in the language. The compiler can make only limited use of it.
August 02, 2014
On 8/1/2014 5:57 PM, Dicebot wrote:
> `enforce` does have overload which allows to use pre-allocated exception
> instance. Or, alternatively, we may need a similar helper wich does `if
> (!condition) abort()` with no interaction with -release or optimizer.

It still throws a *recoverable* exception, which requires the call stack to be populated with exception handling frames. Worse, it implies that program bugs are recoverable errors, when they are not.


> 1) one can always `enforce` with a pre-allocated Error, will druntime handle
> that as expected?

I don't know, but I don't see why not.


> 2) There is certain class of applications where even programming bugs can (and
> must be) considered recoverable. Network services that don't yet have full scale
> high availability infrastructure (and thus can't afford downtime of restarting
> the app) are quite likely to only terminate connection fibers when programming
> bug is found - it does not affect serving any other connections. It may be
> fundamentally wrong but is is pragmatical working approach.
>
> These questions are not theoretical - we regularly have discussion about how
> contracts may / should be used at work with no clear understanding / agreement
> so far. I am interested in simple set of guidelines that won't turn writing
> every single function in a guessing game (does a contract fit here?)

Putting it another way, consider the rules:

1. A newbie follows the rules because he's told to
2. A master follows the rules because he knows why the rules are good
3. A guru breaks the rules because he knows when the rules don't apply

As to the substance of your question, I can't do it proper justice in a few lines. It's an important issue, and it is worthwhile to thoroughly understand it, especially for the kind of programming you do and the leading role you have in it.

For that I recommend "Object Oriented Software Construction" by Meyers.

http://www.amazon.com/Object-Oriented-Software-Construction-Book-CD-ROM/dp/0136291554/

Don't let the OOP title throw you off. It is a very thorough treatment of contract programming, and the rules and their rationales, but in a readable manner. You won't be sorry you read it. It's only $34 used, a bargain.
August 02, 2014
On 08/02/2014 07:56 AM, eles wrote:
> On Friday, 1 August 2014 at 20:22:39 UTC, Tofu Ninja wrote:
>> On Friday, 1 August 2014 at 20:16:29 UTC, eles wrote:
>>
>>> Yes, but is the same for the C apps. There, you have no assertion in
>>> the release build, the release build is optimized (I imagine very few
>>> would use -O0 on it...), then the sefault happens.
>>>
>>
>> In c the assert is just a check, no assume, the Microsoft compiler
>> even has its own __assume separate from assert.
>
> Because the assert is in the library, not in the language. The compiler
> can make only limited use of it.

It's part of the language standard. The compiler can make as much use of it as possible while still conforming to the spec.