February 05, 2015
On Thursday, 5 February 2015 at 06:15:39 UTC, H. S. Teoh wrote:
> On Thu, Feb 05, 2015 at 05:42:57AM +0000, Meta via Digitalmars-d wrote:
> [...]
>> I don't know about others (besides Beatophile, who religiously adheres
>> to writing contacts), but putting contracts on functions is a hassle.
>> I never do it unless I'm feeling particularly full of divine fervor.
>> It's a lot like making all variables that don't need to be changed
>> immutable (another thing which only Bearophile seems to do) or
>> properly documenting code. Strong optimization guarantees from
>> contracts would go a long way in convincing people to actually write
>> them (although I guess that's not what you want; Perhaps you changed
>> your mind). It's a chicken and egg problem.
>
> I do write contracts in my own code, though not as much as I would've
> because (1) the syntax is far too verbose, (2) dmd makes a mess of DbC
> by putting in-contracts in the callee rather than the caller, causing
> severe limitations in real-life usage, and (3) so far optimizations
> based on contracts (esp. via assert/assume, that Walter was so insistent
> on) haven't materialized yet.
>
> But then again, I do like to document my code a lot too, so maybe I'm
> just One Of Those People. *shrug* (I'm not as extreme as bearophile in
> insisting on putting immutable everywhere, though. Not yet, anyway. :-P)
>
>
> T

I've found that the more years of experience I have under my belt, the less documentation I wrote. When I was starting out I was very diligent in doing everything the Correct Way so as to cultivate good habits. I'd find my regression over the years more alarming if I cared enough.
February 05, 2015
"Meta"  wrote in message news:ejqtxksoifmqzetllaqw@forum.dlang.org...

> I don't know about others (besides Beatophile, who religiously adheres to writing contacts), but putting contracts on functions is a hassle. I never do it unless I'm feeling particularly full of divine fervor. It's a lot like making all variables that don't need to be changed immutable (another thing which only Bearophile seems to do) or properly documenting code. Strong optimization guarantees from contracts would go a long way in convincing people to actually write them (although I guess that's not what you want; Perhaps you changed your mind). It's a chicken and egg problem.

Would you be more likely to write contracts if something like this was implemented?
https://github.com/D-Programming-Language/dmd/pull/3799

I want to check contracts at compile time, when possible.  For me this would make contracts 1000x more useful. 

February 05, 2015
On Thursday, 5 February 2015 at 06:26:17 UTC, Meta wrote:
> I've found that the more years of experience I have under my belt, the less documentation I wrote. When I was starting out I was very diligent in doing everything the Correct Way so as to cultivate good habits. I'd find my regression over the years more alarming if I cared enough.

$0.02:

I personally use contracts quite a lot to tighten the screws on my interfaces. I don't like writing documentation, mostly on account of I refactor so aggressively it winds up being wasted effort in a lot of cases (though I do make notes when I think something is complex enough to forget or unlikely to change), so instead I opt to "document" via unittest and assert messages in contracts.

One of my main internal packages consists of a set of mixin templates that generate operators from supplied primitives. The release runtime is meant to be light, and mostly offers syntactic sugar (more importantly, unified interfaces with predictable semantics) so code for each layer winds up being between 1:1 and 60:1 contract to body.

From a documentation perspective, being able to open up the "out" block and see that the enclosing struct's length values must reflect the values passed to the allocation primitive is nice. Being able to open up the "body" block and see, without the clutter of all the bounds checks and whatnot, opIndex just forwards the call to the access primitive in one line - also nice.

I love dbC in D. I think in/out makes things clean and obvious. I could care less about the line count, I use code-folding anyway.
February 05, 2015
On Thursday, 5 February 2015 at 06:51:35 UTC, Vlad Levenfeld wrote:
> I could care less

Er, stupid but unfortunately common american english idiom. For non-native speakers, I mean to say I could NOT care less.
February 05, 2015
On Thursday, 5 February 2015 at 04:36:39 UTC, Zach the Mystic wrote:
> I have an idea. Treat all assert statements which come before the first non-assert statement as part of the 'in' contract. I'm not saying the compiler has to generate a whole 'in' function, but these asserts can be internally tagged to behave *as if* in an 'in' contract. That solves the tooling problem and the too-much-code problem, no?

No. There is no point of screwing up the language because an arbitrary choice of formating is taking an absurd amount of vertical space.
February 05, 2015
On Thursday, 5 February 2015 at 06:15:39 UTC, H. S. Teoh wrote:
> On Thu, Feb 05, 2015 at 05:42:57AM +0000, Meta via Digitalmars-d wrote:
> [...]
>> I don't know about others (besides Beatophile, who religiously adheres
>> to writing contacts), but putting contracts on functions is a hassle.
>> I never do it unless I'm feeling particularly full of divine fervor.
>> It's a lot like making all variables that don't need to be changed
>> immutable (another thing which only Bearophile seems to do) or
>> properly documenting code. Strong optimization guarantees from
>> contracts would go a long way in convincing people to actually write
>> them (although I guess that's not what you want; Perhaps you changed
>> your mind). It's a chicken and egg problem.
>
> I do write contracts in my own code, though not as much as I would've
> because (1) the syntax is far too verbose, (2) dmd makes a mess of DbC
> by putting in-contracts in the callee rather than the caller, causing
> severe limitations in real-life usage, and (3) so far optimizations
> based on contracts (esp. via assert/assume, that Walter was so insistent
> on) haven't materialized yet.
>
> But then again, I do like to document my code a lot too, so maybe I'm
> just One Of Those People. *shrug* (I'm not as extreme as bearophile in
> insisting on putting immutable everywhere, though. Not yet, anyway. :-P)
>
>
> T

I miss the point about in.

DbC as presentend by Eiffel and adopted in .NET, Ada among others, the complete contract is on the  callee.

It doesn't make sense otherwise.
February 05, 2015
On Thursday, 5 February 2015 at 07:28:36 UTC, Paulo Pinto wrote:
> I miss the point about in.
>
> DbC as presentend by Eiffel and adopted in .NET, Ada among others, the complete contract is on the  callee.
>
> It doesn't make sense otherwise.

Conceptually the precondition is a specification that the caller has to guarantee, and the postcondition is a specification that the callee guarantees. The enforcement of the contract specification should be done by the build system which is "neutral".

I.e. the contractors who wrote the code for the callers and callees may try to subvert the contract, but the build system should ideally prevent this. This is of course messed up in D, since you don't have a separate specification independent of the implementation, but you could still verify the D code against a specification to prevent contractors from subverting contracts.

The thought of having the signature/specification before the implementation was a good one, but readability suffers from having all the braces. So the D syntax is not as usable as it should be.

I think D should do this in the body like other languages:

func(){
   @require(...);
   @ensure(…);
   ... function body ...
}

or

func(){
   @pre(...);
   @post(…);
   ... function body ...
}

or

func(){
   pre_assert(...);
   post_assert(…);
   ... function body ...
}




February 05, 2015
On Wednesday, February 04, 2015 16:24:14 Andrei Alexandrescu via Digitalmars-d wrote:
> I'm seeing another idiom that seems to become fashionable. Consider this
> excerpt from
> https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm/iteration.d#L407:
>
>              auto opSlice(size_t low, size_t high)
>              in
>              {
>                  assert(low <= high);
>              }
>              body
>              {
>                  import std.range : take;
>                  return this[low .. $].take(high - low);
>              }
>
> which of course trivially boils down to:
>
>              auto opSlice(size_t low, size_t high)
>              {
>                  assert(low <= high);
>                  import std.range : take;
>                  return this[low .. $].take(high - low);
>              }
>
> What advantage could possibly be in transforming a 5-liner into a 9-liner? Are we really aiming at writing the maximum possible lines of code here and using as many language features as possible everywhere?
>
> I think we should dust off that Phobos contributors' guide. Sadly, there is little we can do against the more subtle issues.

As far as I can tell, there is zero reason to use in blocks aside from with classes, since with virtual functions, inheritance comes into play, and the semantics aren't the same. But for the vast majority of functions, I totally agree that using an in block is just visual noise.

Similarly, I think that out blocks are pretty useless. They're of some value when you have multiple return statements and want to check something when the function exits, but in the vast majority of cases, what you're testing with an out contract is what unit tests would be testing, in which case, the out blocks don't really add anything, and since they're forced to be general, you can't test for specific results like you can with a unit test. Sometimes, testing something in the out block can be useful, but in my experience, unit tests almost always take care of it.  So, in most cases, out contract blocks don't really add anything IMHO and are pretty pointless (though the exception of virtual functions applies in this case as well).

So, while I totally agree that contract programming is valuable, I don't think that the special syntax that D provides for it is of much value except in the case of virtual functions. And the fact that that syntax is so noisy (especially when there's only one assertion) makes it kind of ridiculous IMHO to use in blocks or out blocks on non-virtual functions.

- Jonathan M Davis

February 05, 2015
On Thursday, February 05, 2015 01:33:54 David Nadlinger via Digitalmars-d wrote:
> On Thursday, 5 February 2015 at 01:09:15 UTC, Andrei Alexandrescu wrote:
> > Non-debug mode removes asserts statically. -- Andrei
>
> Using pre-/post-conditions allows the _caller_ to specify whether the checks are run without recompiling the function body, at least in theory.

In theory, yes. And then in blocks would provide some value outside of virtual functions. But as it stands, there is _zero_ semantic difference between

void foo(int i)
in
{
    assert(i > 0);
}
body
{
    ...
}

and

void foo(int i)
{
    assert(i > 0);
    ...
}

And unless we make some serious changes to how D functions are called, I don't see how it could possibly be otherwise. in and out blocks and invariants are not part of the function signature. They're implementation details that disappear when prototypes are used.

So, while in principle, it would be great if assertions related to contracts were enabled or disabled by the caller, not only does it not work that way now, I have no idea how it even could work that way.

- Jonathan M Davis

February 05, 2015
On Thursday, 5 February 2015 at 08:01:06 UTC, Jonathan M Davis wrote:
> the function exits, but in the vast majority of cases, what you're testing
> with an out contract is what unit tests would be testing, in which case, the
> out blocks don't really add anything, and since they're forced to be
> general, you can't test for specific results like you can with a unit test.

That would be true if:
- the unit test was doing exhaustive testing
- the unit test is fully specified
- the unit test is proven correct

But post conditions that are part of a specification can in theory be used for optimization when you link object files from different sources. So you can change the implementation of one object file with only linking as long as the specification itself does not change. Well, if you had a separate specification...