February 07, 2005
Dave wrote:

> Maybe I missed something, but what's the difference between
>>Programming with Contracts (PwC) and Design by Contract (DbC) ?

> If the consensus here is that DbC is the better blanket term,
> I'll be more than happy to use that.

Nah, it was only that I had to look it up myself,
- AFAIK, it stood for PricewaterhouseCoopers :-)

The D spec only used Design by Contract™, though.
As in http://www.digitalmars.com/d/dbc.html

"Design by Contract" is now a trademark by Eiffel Software.
(yet another reason to use a generic: Contract Programming)

But "Contracts" seems to be a simple enough term to use ?
(otherwise we'll just debate "in/out" vs. "pre/post"...)


There does seem to be quite the confusion about contracts
vs. exceptions vs. unittests vs. release vs. whatever, so
anything specific added to the D language spec helps here.

--anders

February 07, 2005
In article <cu8bdv$389$1@digitaldaemon.com>, =?windows-1252?Q?Anders_F_Bj=F6rklund?= says...
>
>Dave wrote:
>
>> Maybe I missed something, but what's the difference between
>>>Programming with Contracts (PwC) and Design by Contract (DbC) ?
>
>> If the consensus here is that DbC is the better blanket term, I'll be more than happy to use that.
>
>Nah, it was only that I had to look it up myself,
>- AFAIK, it stood for PricewaterhouseCoopers :-)
>
>The D spec only used Design by Contract™, though.
>As in http://www.digitalmars.com/d/dbc.html
>
>"Design by Contract" is now a trademark by Eiffel Software. (yet another reason to use a generic: Contract Programming)
>
>But "Contracts" seems to be a simple enough term to use ? (otherwise we'll just debate "in/out" vs. "pre/post"...)
>
>
>There does seem to be quite the confusion about contracts vs. exceptions vs. unittests vs. release vs. whatever, so anything specific added to the D language spec helps here.
>
>--anders
>

I'd just like to point out that DbC is but a subset of AOP. The latter wields some pretty awesome mechanics for 'instrumenting' code, in highly managable and ulimately configurable ways. Where DbC is about manually instrumenting each method and class, AOP subsumes that and extends it across classes; across behavior. It would seem to be a perfect match for the stated goals of D.

Note that some 'aspects' of AOP relate to the injection of code before and after a particular set of methods is executed. D supports this via in{} and out{} constructs, plus invariant{}. This is why, I imagine, one can write an AOP preprocessor for D. However, AOP goes far beyond that. I encourage all to read up on AOP, just to see what the potential is.

Why does this relate to the -release switch? The D version{} feature could be leveraged to enable/disable broad swathes of AOP functionality, at a high & adroitly manageable level. This would represent the ultimate in controlling which particular tests are retained for any given compile.

- Kris




February 07, 2005
Paul Bonser wrote:
> Some mention of license problems got me thinking about this piece of standard Sun boilerplate:
> 
> "Nuclear, missile, chemical biological weapons or nuclear maritime end uses or end users, whether direct or indirect, are strictly prohibited."
> 
> Are we going to have that kind of restrictions on D, or will we be free to use it to guide weapons of mass destruction? :P
> 

Leave it to you guys to take a perfectly good semi-off-topic thread and bring it onto a topic :P

-- 
-PIB

--
"C++ also supports the notion of *friends*: cooperative classes that
are permitted to see each other's private parts." - Grady Booch
February 07, 2005
I'm jumping into this at a somewhat arbitrary point, but the general claim Walter (apparently) makes is that

1) D tries to catch dumb mistakes made by a user
2) D tries to steer the programmer in the 'right' direction

Let's see here:

char[] getLine (char[] s)
{
uint length = s.length;
foreach (uint i, char c; s)
{
if (c == '\n')
length = i;
}
return s [0..length];
}

The above is just an arbitrary example of the apparent hypocritical nature of
(1) and (2). The function is supposed to return the subset of its argument only
as far as a newline.

Do you see the insideous bug there? Many of you will not, so I'll spell it out:

Walter added a very subtle pseudo-reserved word, that's only used when it comes to arrays. Yes, it's the word "length". When used within square-brackets, it always means "the length of the enclosing array". Of course, this overrides any other variable that happens to be called "length". Naturally, no warning is emitted.

This would perhaps not be so bad if the pseudo-reserved word were "implicitArrayLength" or something like that. But NO! Walter uses an undecorated, and exceptionally common variable name instead. Oh; and this was introduced to ease the implementation of certain templates - on technical merits. Oh! And Walter feels this pseudo-reserved name should /not/ change from "length" to a 'decorated' version instead.

Any talk about D with regard to (1) and (2) are moot, when D clearly injects
subtle and glorious ways to f%ck the programmer in simple, and shall I say
common, ways.

Fair warning :-)

I fully sympathize with your head-beating-wall exercise, Matthew. Keep it up!





In article <cu44i1$739$1@digitaldaemon.com>, Walter says...
>
>
>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu3v58$3c3$1@digitaldaemon.com...
>> A maintenance engineer is stymied by *both*
>> forms, and confused contrarily: the first looks like a bug but may not
>> be, the second is a bug but doesn't look like it. The only form that
>> stands up to maintenance is something along the lines of what Derek's
>> talking about:
>>
>>     int foo(CollectionClass c, int y)
>>     {
>>         foreach (Value v; c)
>>         {
>>             if (v.x == y)
>
>                 return v.z;
>>         }
>>
>>         throw logic_error("This function has encountered a situation
>> which contradicts its design and/or the design of the software within
>> which it resides");
>>
>>         return 0;
>>     }
>
>From a C/C++ perspective, you're right, this is the only correct solution. From a D perspective, however, I submit that the first example is not confusing. There is no falling off the end in D functions, as an exception would be thrown. The only returns that can happen are explicitly there with return statements. The maintenance engineer will know this as surely as he knows that after an assert(p) that p is not null. I agree this is a different way of thinking about the code, that coming from a solid C/C++ background it might be a bit off-putting.
>
>> This is what I also do in such cases, and I believe (and have witnessed) it being a widely practiced technique.
>
>Yes, and I've written magazine articles and done lectures pushing exactly that. It's what one has to do with C/C++.
>
>>You're
>> keen to mould D with a view to catering for, or at least mitigating the actions of,  the lowest common denominators of the programming gene pool.
>
>I've seen this kind of error written by experts, not just the lowest common denominator. If D cannot prevent an error, it should try to mitigate the damage.
>
>>Yet you seem decidely uninterested in addressing the concerns of
>> large scale and/or commercial and/or large-teams and/or long-lasting codebases. How can this attitude help D to prosper?
>
>I have to disagree with this. Many features of D are the result of many long conversations with program development managers. They need positive mechanisms in the language to prevent or at least mitigate the effects of common, very human, programming mistakes. C and C++ are seriously deficient in this area. That you disagree with the efficacy of one the solutions does not at all mean I am uninterested. A very large part of D is providing support for writing robust code.
>
>> Your measure adds an indeterminately timed exception fire, in the case that a programmer doesn't add a return 0. That's great, so far as it goes. But here's the fly in your soup: what's to stop them adding the return 0?
>
>Absolutely nothing. But as I wrote before, if he's looking at fixing the code after the exception fired, he knows he's dealing with a bug that needs fixing. In the case of the compiler error message, there is not necessarilly a bug there, so the easy temptation is to throw in a return of some arbitrary value. Is that bad programming technique? Absolutely. Does it happen anyway? Yes, it does. I've been in code review meetings and listened to the excuses for it. Those kinds of things are hard to pick up in a code review, so removing the cause of it and trying to mitigate the damage is of net benefit.
>
>Let's put it this way, here are the choices (numbers pulled out of dimension
>X):
>
>1) A bug catching feature that 90% of the time will cause the programmer to write correct code, but 10% of the time will result in code that has an insidious, nasty, hard to reproduce & find bug.
>
>2) A bug catching feature that 70% of the time will cause the programmer to write correct code, but the 30% that get it wrong results in code that when it fails, fails cleanly, in an easy to reproduce, find and therefore fixable manner.
>
>It's a judgement call, not dogma. I'd rather have (2), and I believe that
>(2) is better for the long term success of a code base. I do not like (1), b
>ecause the penalties of such bugs, even though they are less frequent, are
>so severe they overshadows everything else.
>
>


February 07, 2005
I agree 'length' seems to be poorly implemented, or perhaps is simply a bad idea. I think using a symbol like $ is better for this very reason.

It should be an "error" IMO (not a warning) to 'hide' a variable from an enclosing scope. There could be 3 options for avoiding this error:

1. rename the variable or the enclosing variable

2. specify the reference in full. We can specify the enclosing variable in full, but we need to be able to say <in this scope>.varname also.

3. use an alias, we need some way to pick the preferred variable i.e. the inner variable, allowing you to specify the enclosing var in full.


Regardless, either you're arguing that because this is bad about D, the missing return behaviour must also be bad, which is clearly illogical.

Or, this post is simply an attack designed to make Walters position seem weaker, when in fact it supplies no logical evidence to do so.

In other words I can't see how this post has any bearing on the argument at hand. At best it's a strawman:
http://www.datanation.com/fallacies/straw.htm

On Mon, 7 Feb 2005 19:47:15 +0000 (UTC), Kris <Kris_member@pathlink.com> wrote:
> I'm jumping into this at a somewhat arbitrary point, but the general claim
> Walter (apparently) makes is that
>
> 1) D tries to catch dumb mistakes made by a user
> 2) D tries to steer the programmer in the 'right' direction
>
> Let's see here:
>
> char[] getLine (char[] s)
> {
> uint length = s.length;
> foreach (uint i, char c; s)
> {
> if (c == '\n')
> length = i;
> }
> return s [0..length];
> }
>
> The above is just an arbitrary example of the apparent hypocritical nature of
> (1) and (2). The function is supposed to return the subset of its argument only
> as far as a newline.
>
> Do you see the insideous bug there? Many of you will not, so I'll spell it out:
>
> Walter added a very subtle pseudo-reserved word, that's only used when it comes
> to arrays. Yes, it's the word "length". When used within square-brackets, it
> always means "the length of the enclosing array". Of course, this overrides any
> other variable that happens to be called "length". Naturally, no warning is
> emitted.
>
> This would perhaps not be so bad if the pseudo-reserved word were
> "implicitArrayLength" or something like that. But NO! Walter uses an
> undecorated, and exceptionally common variable name instead. Oh; and this was
> introduced to ease the implementation of certain templates - on technical
> merits. Oh! And Walter feels this pseudo-reserved name should /not/ change from
> "length" to a 'decorated' version instead.
>
> Any talk about D with regard to (1) and (2) are moot, when D clearly injects
> subtle and glorious ways to f%ck the programmer in simple, and shall I say
> common, ways.
>
> Fair warning :-)
>
> I fully sympathize with your head-beating-wall exercise, Matthew. Keep it up!
>
>
>
>
>
> In article <cu44i1$739$1@digitaldaemon.com>, Walter says...
>>
>>
>> "Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message
>> news:cu3v58$3c3$1@digitaldaemon.com...
>>> A maintenance engineer is stymied by *both*
>>> forms, and confused contrarily: the first looks like a bug but may not
>>> be, the second is a bug but doesn't look like it. The only form that
>>> stands up to maintenance is something along the lines of what Derek's
>>> talking about:
>>>
>>>     int foo(CollectionClass c, int y)
>>>     {
>>>         foreach (Value v; c)
>>>         {
>>>             if (v.x == y)
>>
>>                 return v.z;
>>>         }
>>>
>>>         throw logic_error("This function has encountered a situation
>>> which contradicts its design and/or the design of the software within
>>> which it resides");
>>>
>>>         return 0;
>>>     }
>>
>> From a C/C++ perspective, you're right, this is the only correct solution.
>> From a D perspective, however, I submit that the first example is not
>> confusing. There is no falling off the end in D functions, as an exception
>> would be thrown. The only returns that can happen are explicitly there with
>> return statements. The maintenance engineer will know this as surely as he
>> knows that after an assert(p) that p is not null. I agree this is a
>> different way of thinking about the code, that coming from a solid C/C++
>> background it might be a bit off-putting.
>>
>>> This is what I also do in such cases, and I believe (and have witnessed)
>>> it being a widely practiced technique.
>>
>> Yes, and I've written magazine articles and done lectures pushing exactly
>> that. It's what one has to do with C/C++.
>>
>>> You're
>>> keen to mould D with a view to catering for, or at least mitigating the
>>> actions of,  the lowest common denominators of the programming gene
>>> pool.
>>
>> I've seen this kind of error written by experts, not just the lowest common
>> denominator. If D cannot prevent an error, it should try to mitigate the
>> damage.
>>
>>> Yet you seem decidely uninterested in addressing the concerns of
>>> large scale and/or commercial and/or large-teams and/or long-lasting
>>> codebases. How can this attitude help D to prosper?
>>
>> I have to disagree with this. Many features of D are the result of many long
>> conversations with program development managers. They need positive
>> mechanisms in the language to prevent or at least mitigate the effects of
>> common, very human, programming mistakes. C and C++ are seriously deficient
>> in this area. That you disagree with the efficacy of one the solutions does
>> not at all mean I am uninterested. A very large part of D is providing
>> support for writing robust code.
>>
>>> Your measure adds an indeterminately timed exception fire, in the case
>>> that a programmer doesn't add a return 0. That's great, so far as it
>>> goes. But here's the fly in your soup: what's to stop them adding the
>>> return 0?
>>
>> Absolutely nothing. But as I wrote before, if he's looking at fixing the
>> code after the exception fired, he knows he's dealing with a bug that needs
>> fixing. In the case of the compiler error message, there is not necessarilly
>> a bug there, so the easy temptation is to throw in a return of some
>> arbitrary value. Is that bad programming technique? Absolutely. Does it
>> happen anyway? Yes, it does. I've been in code review meetings and listened
>> to the excuses for it. Those kinds of things are hard to pick up in a code
>> review, so removing the cause of it and trying to mitigate the damage is of
>> net benefit.
>>
>> Let's put it this way, here are the choices (numbers pulled out of dimension
>> X):
>>
>> 1) A bug catching feature that 90% of the time will cause the programmer to
>> write correct code, but 10% of the time will result in code that has an
>> insidious, nasty, hard to reproduce & find bug.
>>
>> 2) A bug catching feature that 70% of the time will cause the programmer to
>> write correct code, but the 30% that get it wrong results in code that when
>> it fails, fails cleanly, in an easy to reproduce, find and therefore fixable
>> manner.
>>
>> It's a judgement call, not dogma. I'd rather have (2), and I believe that
>> (2) is better for the long term success of a code base. I do not like (1), b
>> ecause the penalties of such bugs, even though they are less frequent, are
>> so severe they overshadows everything else.
>>
>>
>
>

February 07, 2005
On Mon, 7 Feb 2005 19:47:15 +0000 (UTC), Kris wrote:

> I'm jumping into this at a somewhat arbitrary point, but the general claim Walter (apparently) makes is that
> 
> 1) D tries to catch dumb mistakes made by a user
> 2) D tries to steer the programmer in the 'right' direction
> 
> Let's see here:
> 
> char[] getLine (char[] s)
> {
> uint length = s.length;
> foreach (uint i, char c; s)
> {
> if (c == '\n')
> length = i;
> }
> return s [0..length];
> }
> 
> The above is just an arbitrary example of the apparent hypocritical nature of
> (1) and (2). The function is supposed to return the subset of its argument only
> as far as a newline.
> 
> Do you see the insideous bug there? Many of you will not, so I'll spell it out:
> 
> Walter added a very subtle pseudo-reserved word, that's only used when it comes to arrays. Yes, it's the word "length". When used within square-brackets, it always means "the length of the enclosing array". Of course, this overrides any other variable that happens to be called "length". Naturally, no warning is emitted.
> 
> This would perhaps not be so bad if the pseudo-reserved word were "implicitArrayLength" or something like that. But NO! Walter uses an undecorated, and exceptionally common variable name instead. Oh; and this was introduced to ease the implementation of certain templates - on technical merits. Oh! And Walter feels this pseudo-reserved name should /not/ change from "length" to a 'decorated' version instead.

And this is one of the reason why I use 'decorated' identifier names; to avoid clashes with language keywords.

 char[] getLine (char[] pString)
 {
 uint lLength = pString.length;
 foreach (uint fIdx, char fCurrChar; pString)
 {
 if (fCurrChar == '\n')
 lLength = fIdx;
 }
 return pString [0..lLength];
 }

(The prefixes give hints as to the identifiers' scope)
-- 
Derek
Melbourne, Australia
February 07, 2005
Derek wrote:

> And this is one of the reason why I use 'decorated' identifier names;

I'm not sure that warts classifies as decorations in all cultures ? :-)

http://www.digitalmars.com/d/dstyle.html:
> Hungarian Notation
> Just say no.

--anders
February 07, 2005
On Mon, 07 Feb 2005 22:21:25 +0100, Anders F Björklund wrote:

> Derek wrote:
> 
>> And this is one of the reason why I use 'decorated' identifier names;
> 
> I'm not sure that warts classifies as decorations in all cultures ? :-)
> 
> http://www.digitalmars.com/d/dstyle.html:
>> Hungarian Notation
>> Just say no.
> 

Well its been working for me and my teams for 10 years now, so sue me. ;-)

-- 
Derek
Melbourne, Australia
February 07, 2005
I'm afraid I was out working + book writing when that went in. Very poor form indeed. (And you're quite right that it totally takes the legs out from Walter's arguments on missing returns.)

:-(

"Kris" <Kris_member@pathlink.com> wrote in message news:cu8gk2$e0a$1@digitaldaemon.com...
> I'm jumping into this at a somewhat arbitrary point, but the general
> claim
> Walter (apparently) makes is that
>
> 1) D tries to catch dumb mistakes made by a user
> 2) D tries to steer the programmer in the 'right' direction
>
> Let's see here:
>
> char[] getLine (char[] s)
> {
> uint length = s.length;
> foreach (uint i, char c; s)
> {
> if (c == '\n')
> length = i;
> }
> return s [0..length];
> }
>
> The above is just an arbitrary example of the apparent hypocritical
> nature of
> (1) and (2). The function is supposed to return the subset of its
> argument only
> as far as a newline.
>
> Do you see the insideous bug there? Many of you will not, so I'll spell it out:
>
> Walter added a very subtle pseudo-reserved word, that's only used when
> it comes
> to arrays. Yes, it's the word "length". When used within
> square-brackets, it
> always means "the length of the enclosing array". Of course, this
> overrides any
> other variable that happens to be called "length". Naturally, no
> warning is
> emitted.
>
> This would perhaps not be so bad if the pseudo-reserved word were
> "implicitArrayLength" or something like that. But NO! Walter uses an
> undecorated, and exceptionally common variable name instead. Oh; and
> this was
> introduced to ease the implementation of certain templates - on
> technical
> merits. Oh! And Walter feels this pseudo-reserved name should /not/
> change from
> "length" to a 'decorated' version instead.
>
> Any talk about D with regard to (1) and (2) are moot, when D clearly
> injects
> subtle and glorious ways to f%ck the programmer in simple, and shall I
> say
> common, ways.
>
> Fair warning :-)
>
> I fully sympathize with your head-beating-wall exercise, Matthew. Keep it up!
>
>
>
>
>
> In article <cu44i1$739$1@digitaldaemon.com>, Walter says...
>>
>>
>>"Matthew" <admin@stlsoft.dot.dot.dot.dot.org> wrote in message news:cu3v58$3c3$1@digitaldaemon.com...
>>> A maintenance engineer is stymied by *both*
>>> forms, and confused contrarily: the first looks like a bug but may
>>> not
>>> be, the second is a bug but doesn't look like it. The only form that
>>> stands up to maintenance is something along the lines of what
>>> Derek's
>>> talking about:
>>>
>>>     int foo(CollectionClass c, int y)
>>>     {
>>>         foreach (Value v; c)
>>>         {
>>>             if (v.x == y)
>>
>>                 return v.z;
>>>         }
>>>
>>>         throw logic_error("This function has encountered a situation
>>> which contradicts its design and/or the design of the software
>>> within
>>> which it resides");
>>>
>>>         return 0;
>>>     }
>>
>>From a C/C++ perspective, you're right, this is the only correct
>>solution.
>>From a D perspective, however, I submit that the first example is not
>>confusing. There is no falling off the end in D functions, as an
>>exception
>>would be thrown. The only returns that can happen are explicitly there
>>with
>>return statements. The maintenance engineer will know this as surely
>>as he
>>knows that after an assert(p) that p is not null. I agree this is a
>>different way of thinking about the code, that coming from a solid
>>C/C++
>>background it might be a bit off-putting.
>>
>>> This is what I also do in such cases, and I believe (and have
>>> witnessed)
>>> it being a widely practiced technique.
>>
>>Yes, and I've written magazine articles and done lectures pushing
>>exactly
>>that. It's what one has to do with C/C++.
>>
>>>You're
>>> keen to mould D with a view to catering for, or at least mitigating
>>> the
>>> actions of,  the lowest common denominators of the programming gene
>>> pool.
>>
>>I've seen this kind of error written by experts, not just the lowest
>>common
>>denominator. If D cannot prevent an error, it should try to mitigate
>>the
>>damage.
>>
>>>Yet you seem decidely uninterested in addressing the concerns of
>>> large scale and/or commercial and/or large-teams and/or long-lasting codebases. How can this attitude help D to prosper?
>>
>>I have to disagree with this. Many features of D are the result of
>>many long
>>conversations with program development managers. They need positive
>>mechanisms in the language to prevent or at least mitigate the effects
>>of
>>common, very human, programming mistakes. C and C++ are seriously
>>deficient
>>in this area. That you disagree with the efficacy of one the solutions
>>does
>>not at all mean I am uninterested. A very large part of D is providing
>>support for writing robust code.
>>
>>> Your measure adds an indeterminately timed exception fire, in the
>>> case
>>> that a programmer doesn't add a return 0. That's great, so far as it
>>> goes. But here's the fly in your soup: what's to stop them adding
>>> the
>>> return 0?
>>
>>Absolutely nothing. But as I wrote before, if he's looking at fixing
>>the
>>code after the exception fired, he knows he's dealing with a bug that
>>needs
>>fixing. In the case of the compiler error message, there is not
>>necessarilly
>>a bug there, so the easy temptation is to throw in a return of some
>>arbitrary value. Is that bad programming technique? Absolutely. Does
>>it
>>happen anyway? Yes, it does. I've been in code review meetings and
>>listened
>>to the excuses for it. Those kinds of things are hard to pick up in a
>>code
>>review, so removing the cause of it and trying to mitigate the damage
>>is of
>>net benefit.
>>
>>Let's put it this way, here are the choices (numbers pulled out of
>>dimension
>>X):
>>
>>1) A bug catching feature that 90% of the time will cause the
>>programmer to
>>write correct code, but 10% of the time will result in code that has
>>an
>>insidious, nasty, hard to reproduce & find bug.
>>
>>2) A bug catching feature that 70% of the time will cause the
>>programmer to
>>write correct code, but the 30% that get it wrong results in code that
>>when
>>it fails, fails cleanly, in an easy to reproduce, find and therefore
>>fixable
>>manner.
>>
>>It's a judgement call, not dogma. I'd rather have (2), and I believe
>>that
>>(2) is better for the long term success of a code base. I do not like
>>(1), b
>>ecause the penalties of such bugs, even though they are less frequent,
>>are
>>so severe they overshadows everything else.
>>
>>
>
> 


February 07, 2005
> Regardless, either you're arguing that because this is bad about D, the  missing return behaviour must also be bad, which is clearly illogical.

He's not saying that at all.

> Or, this post is simply an attack designed to make Walters position seem  weaker, when in fact it supplies no logical evidence to do so.

Oh come on! It goes to the motivation behind the missing return value. Plain as the nose on your face.

> In other words I can't see how this post has any bearing on the argument  at hand. At best it's a strawman: http://www.datanation.com/fallacies/straw.htm

Yawn! Keep trotting 'em out. They must be important and apposite, if there's a link you can reference.



3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19