July 31, 2014
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:
> I am not terribly good at writing formal legalese specifications for this. I welcome PR's to improve the specification along these lines, if you find any Aha! Gotcha! issues in it. Of course, implementation errors for this in DMD should be reported on bugzilla.

What is missing is not formal specification but clear guidelines "how to use this system in production". Right now it is pretty clear that you have implemented something that non-zero amount of experienced D developers have no clue how to use without botching the application completely. This does indicate that something is wrong with the feature even you are perfectly right theoretically.

Currently there is http://dlang.org/contracts.html but neither it nor any of referenced materials does explain to me:

- how to distribute binary library packages in presence of contracts
- how to organize your application to ensure that contracts can be removed in release builds
- are those even applicable to majority of applications

I am less concerned with just assert behavior because there are many ways to workaround it to get different semantics. But contract system... no clues.
July 31, 2014
On Wednesday, 30 July 2014 at 23:50:51 UTC, H. S. Teoh via Digitalmars-d wrote:
> But if you don't want to check ever to be removed, currently you have to
> write:
>
> 	if (!requiredCondition)
> 		assert(0); // compiler never removes this
>
> which IMO is relatively clear, and the use of assert(0) for forceful
> termination is consistent with existing practice in D code.

Not helping.

```
import std.stdio;

void foo()
in { writeln("in contract"); }
body { }

void main() { foo(); }
```

Compile with -release and check the output.
July 31, 2014
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:

> 3. Use of assert to validate input is utterly wrong and will not be supported. Use such constructs at your own risk.

When exactly is it 'ok' to use assert then?

If asserts are not allowed to be used to verify inputs.... then
by extension, they can not be used to verify any derivative of an
input. So by that definition, asserts are only ok to use on any
thing known at compile time... that makes them utterly useless....
July 31, 2014
On 7/30/14, 6:15 PM, Dicebot wrote:
> On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:
>> I am not terribly good at writing formal legalese specifications for
>> this. I welcome PR's to improve the specification along these lines,
>> if you find any Aha! Gotcha! issues in it. Of course, implementation
>> errors for this in DMD should be reported on bugzilla.
>
> What is missing is not formal specification but clear guidelines "how to
> use this system in production". Right now it is pretty clear that you
> have implemented something that non-zero amount of experienced D
> developers have no clue how to use without botching the application
> completely. This does indicate that something is wrong with the feature
> even you are perfectly right theoretically.
>
> Currently there is http://dlang.org/contracts.html but neither it nor
> any of referenced materials does explain to me:
>
> - how to distribute binary library packages in presence of contracts
> - how to organize your application to ensure that contracts can be
> removed in release builds
> - are those even applicable to majority of applications
>
> I am less concerned with just assert behavior because there are many
> ways to workaround it to get different semantics. But contract system...
> no clues.

It would be awesome if you (a) documented formally the current behavior and (b) submit bug reports wherever you find egregious faults in it. -- Andrei
July 31, 2014
On Thursday, 31 July 2014 at 03:52:55 UTC, Andrei Alexandrescu wrote:
> It would be awesome if you (a) documented formally the current behavior and (b) submit bug reports wherever you find egregious faults in it. -- Andrei

It is documented at http://dlang.org/contracts.html
As for bug reports - how can I file those if I have no clue how system is supposed to be used? I don't think it is necessarily bad or buggy, just can't fin the way to make good use of it. Or do you expect "please teach me use contracts" bug report? :)
July 31, 2014
On 7/30/14, 9:01 PM, Dicebot wrote:
> On Thursday, 31 July 2014 at 03:52:55 UTC, Andrei Alexandrescu wrote:
>> It would be awesome if you (a) documented formally the current
>> behavior and (b) submit bug reports wherever you find egregious faults
>> in it. -- Andrei
>
> It is documented at http://dlang.org/contracts.html
> As for bug reports - how can I file those if I have no clue how system
> is supposed to be used? I don't think it is necessarily bad or buggy,
> just can't fin the way to make good use of it. Or do you expect "please
> teach me use contracts" bug report? :)

There's this term "learned helplessness". You're a smart guy who can slice and dice things. -- Andrei

July 31, 2014
On Thursday, 31 July 2014 at 04:24:49 UTC, Andrei Alexandrescu wrote:
> There's this term "learned helplessness". You're a smart guy who can slice and dice things. -- Andrei

This is one of those moments when I am not sure if you are trolling me yet again or being strangely serious. I am supposed to research and propose brand new approach to contract programming because I don't understand how existing one should work? And I am being told that by one of the authors of existing system?

You are taking that "go try yourself" thing way out of proportion.
July 31, 2014
On Wednesday, 30 July 2014 at 22:01:23 UTC, Walter Bright wrote:
> 2. The compiler can make use of assert expressions to improve optimization, even in -release mode.

For the domain I'm currently working in - a
very large codebase (> 1 MLOC, C/C++) for an application program,
I have to echo what others said, and say I could not use such a feature.
I think I can add a reason (though what's been said about the 'fuzzy middle'
between assertions and input validation, certainly rings true for me too).

If my asserts worked this way I would have to stop using them and build my own.
The reason is that, while I tend to assert only things that should be true,
this codebase is not well factored and so:
a) we tend to write a lot of assertions, and
b) occasionally we learn something from them (i.e. an assertion fires,
we go "huh", and our understanding of the codebase improves).

The point is that a priori, we can only guess whether a particular assertion
we're considering adding is really "this program is screwed if this condition
is true".

I don't lose sleep over this because it is safe to add our kind of assertions.
But if adding assertions could affect the optimizer's reasoning, then it would NOT be safe to add them, and we'd have to back way off. I'd be comfortable using such assertions only for very low-level components.

I can see the appeal of allowing the optimizer to do this, but I don't understand the idea of making that the default behavior. To me that's like array bounds-checking being off by default. And speaking of which,
this seems like a useful example:

Surely any program which oversteps the bounds of array, is incorrect?
It must have made some logic error (be it forgetting to validate inputs,
or some internal reasoning that was erroneous). So we should put asserts
on all our array accesses, asserting that they are within bounds!
So... then the optimizer can optimize away all the bounds checks. Releae
builds need no checks of any kind. Right? :)
I'm not trying to be as facetious as that sounds, I'm saying that your position seems to me to lead logically to the conclusion that array bounds-checking
should be off in release.
July 31, 2014
On 7/30/2014 3:39 PM, Joseph Rushton Wakeling via Digitalmars-d wrote:
> My take is that, for this reason, these should be asserts and not enforce()
> statements.  What are your thoughts on the matter?

An excellent question.

First, note that enforce() returns a recoverable exception, and assert() a non-recoverable error.

Logically, this means that enforce() is for scrubbing input, and assert() is for detecting program bugs. I'm pretty brutal in asserting (!) that program bugs are fatal, non-recoverable errors. I've been fighting this battle for decades, i.e. repeated proposals by well-meaning programmers who believe their programs can safely recover from an unknown, invalid state.

Pragmatically, enforce() is significantly more expensive as it uses the GC and callers must support exception safety. Also, take a look at the quantity generated code for the enforce() in the examples, and see how expensive it is. All those lovely messages generate a lot of bloat.

Phobos functions that are designed to scrub input must document so. Otherwise, they should assert.

For LinearCongruentialEngine() and initialize(), passing invalid arguments are programming bugs, and so they should be asserting.
July 31, 2014
On 07/31/2014 12:01 AM, Walter Bright wrote:
(...)
> 2. The compiler can make use of assert expressions to improve optimization, even in -release mode.
(...)

Does this mean that assertions used for optimization will be left in -release? There's plenty of times where I've had an old incorrect assertion in my code after a refactoring - sometimes in seldom used paths.

If the compiler would aggressively optimize my code based on some wrong assumptions I give it, it would be very useful if that assumption would stay in the code to trigger an assertion.