February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | In article <cu8qfi$11q3$1@digitaldaemon.com>, Matthew says... > > >"Derek" <derek@psych.ward> wrote in message news:19f0tg7229js5.y2wq16gmtkq3.dlg@40tude.net... >> 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) > >Very sensible. But very sad that we must do so, given total ugliness of decorations in general, and the almost total uselessness of Hungarian nature. > >The last I recall from last year was that the implicit length was going to be $. I'm sure there were reasons against, but they cannot be as compelling as the example Kris gave. > >Here's a possible compromise, although I'm not sure I like it: > > char[] getLine (char[] s) > { > uint length = s.length; > foreach (uint i, char c; s) > { > if (c == '\n') > length = i; > } > > return s [0 .. .length]; > } > >The . before length indicates its 'local' to 's'. > >Hmmm, on second thoughts, that stinks. > >In general - indeed, it's harder to think of a contrary example - verbose code is better than dangerous code. Kris is quite right when he says that D has introduced some of the latter. > How about: array[from...] // analogous to array[from .. array.length]; - Dave > > |
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | On Mon, 7 Feb 2005 22:38:27 +0000 (UTC), Kris wrote: > In article <1lxyunvbocmz8$.jojxhcylx4ev.dlg@40tude.net>, Derek says... >> >>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. ;-) > > I applaud any group that sets their own standards to deal with complexity; and then sticks with it. > > The issue here is that D slyly injects its own variable named 'length', which > then (a) forces one to adopt just such a standard, once you've hopefully noticed > the bug, and (b) D does not tell you what it did to f&ck you in the first place > :-( > > Given Walter's current position on this particular language 'idiom', one must > resort to (a) > > Hence, one has to adopt a somewhat tongue-in-cheek attitude to lofty claims regarding the goals of D to "protect and serve". I understand Walter invoked the "do as I say, not do as I do" as a rebuke within this thread somewhere. My opinion, and suggestion, is that perhaps he might reflect upon that for a while :-) Sorry I digressed from the main point of your post. I tend to agree with your assessment of the 'length' decision. However, even with that said, and without using decorated identifiers, your example could do with improved identifier naming, for example ... char[] getLine (char[] text_string) { uint newline_position = text_string.length; foreach (uint curr_position, char curr_char; text_string) { if (curr_char == '\n') { newline_position = curr_position; break; } } return text_string [0..newline_position]; } Short identifier names do not always lead to better legibility, just as longer ones do always enhance legibility. But there is a balance that can work. -- Derek Melbourne, Australia 8/02/2005 11:24:10 AM |
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dave | "Dave" <Dave_member@pathlink.com> wrote in message news:cu91eb$1f90$1@digitaldaemon.com... > In article <cu8qfi$11q3$1@digitaldaemon.com>, Matthew says... >> >> >>"Derek" <derek@psych.ward> wrote in message news:19f0tg7229js5.y2wq16gmtkq3.dlg@40tude.net... >>> 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) >> >>Very sensible. But very sad that we must do so, given total ugliness >>of >>decorations in general, and the almost total uselessness of Hungarian >>nature. >> >>The last I recall from last year was that the implicit length was >>going >>to be $. I'm sure there were reasons against, but they cannot be as >>compelling as the example Kris gave. >> >>Here's a possible compromise, although I'm not sure I like it: >> >> char[] getLine (char[] s) >> { >> uint length = s.length; >> foreach (uint i, char c; s) >> { >> if (c == '\n') >> length = i; >> } >> >> return s [0 .. .length]; >> } >> >>The . before length indicates its 'local' to 's'. >> >>Hmmm, on second thoughts, that stinks. >> >>In general - indeed, it's harder to think of a contrary example - >>verbose code is better than dangerous code. Kris is quite right when >>he >>says that D has introduced some of the latter. >> > > How about: > > array[from...] // analogous to array[from .. array.length]; IIRC, that was a popular suggestion at the time, as was array[ .. 2] // from 0 => 2 and array[ .. ] // from 0 => length but they were not accepted. I can't remember why, and they seem ok to me. In neither Ruby nor Python are such things in the least confusing. (Although Ruby's use of inclusive and exclusive ranges via .. and ... gets a little confusing - I'd have to have a look in the book now to tell you which was which.) |
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <cu91gc$1fc7$1@digitaldaemon.com>, Derek Parnell says... <snip> >Short identifier names do not always lead to better legibility, just as longer ones do always enhance legibility. But there is a balance that can work. Amen, Derek. But that's a somewhat different topic. This one is "Compiler support for writing bug free code". The point is that, in this case, the compiler does just the opposite. If I may be so bold: What bother's me is that while Walter acknowledges this issue, he doesn't think it's worthy enough to warrant any attention. This is in rather stark contrast to the "preaching" and "hand clasping" that's somewhat evident in parts of this thread. It would be funny, if it weren't so sad :-) Anyway; I must apologise for drifting this thread away from the original problem, so I'll finish with the following: ultimately, we all want D to be a better language -- not better than C++/Java -- better than D is currently. To that end, we have to point out all of the shortcomings and endevour to have them resolved appropriately. This is why I'm not giving your alternate topic of "better variable names; best practices" the credit it duly & truly deserves, yet keep carping on about the hypocrisy that needs to be rectified :~} Cheers! - Kris |
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew |
>> How about:
>>
>> array[from...] // analogous to array[from .. array.length];
>
>IIRC, that was a popular suggestion at the time, as was
>
> array[ .. 2] // from 0 => 2
>
>and
>
> array[ .. ] // from 0 => length
Unicode to the rescue: array[from..\u221E]
For those who don't immediately recognize \u221E, it is the codepoint for
infinity. :-)
|
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | In article <cu930u$1j33$1@digitaldaemon.com>, Matthew says... >> How about: >> >> array[from...] // analogous to array[from .. array.length]; > >IIRC, that was a popular suggestion at the time, as was > > array[ .. 2] // from 0 => 2 > >and > > array[ .. ] // from 0 => length > >but they were not accepted. I can't remember why, and they seem ok to me. In neither Ruby nor Python are such things in the least confusing. (Although Ruby's use of inclusive and exclusive ranges via .. and ... gets a little confusing - I'd have to have a look in the book now to tell you which was which.) The problem is that one may need to reference the array-length within an expression; an expression within the brackets. This extends to templates, which needed a means to explicitly reference the array length whilst avoiding recanting the array itself (or something like that). The upshot, I understand, was that the notion of an implicit array-length 'temporary' seemed appropriate. Unfortunately it was implemented as a pseudo-reserved "length", rather than an alternate manner that didn't quite shove it up the programmers' proverbial arse |
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kris | "Kris" <Kris_member@pathlink.com> wrote in message news:cu956n$1msm$1@digitaldaemon.com... > In article <cu930u$1j33$1@digitaldaemon.com>, Matthew says... >>> How about: >>> >>> array[from...] // analogous to array[from .. array.length]; >> >>IIRC, that was a popular suggestion at the time, as was >> >> array[ .. 2] // from 0 => 2 >> >>and >> >> array[ .. ] // from 0 => length >> >>but they were not accepted. I can't remember why, and they seem ok to me. In neither Ruby nor Python are such things in the least confusing. (Although Ruby's use of inclusive and exclusive ranges via .. and ... gets a little confusing - I'd have to have a look in the book now to tell you which was which.) > > The problem is that one may need to reference the array-length within > an > expression; an expression within the brackets. Ah, of course. Silly me. > This extends to templates, which > needed a means to explicitly reference the array length whilst > avoiding > recanting the array itself (or something like that). > > The upshot, I understand, was that the notion of an implicit > array-length > 'temporary' seemed appropriate. Unfortunately it was implemented as a > pseudo-reserved "length", rather than an alternate manner that didn't > quite > shove it up the programmers' proverbial arse Indeed |
February 08, 2005 Re: Compiler support for writing bug free code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath |
"Regan Heath" <regan@netwin.co.nz> wrote in message news:opsluof7fx23k2f5@ally...
> On Tue, 8 Feb 2005 09:48:10 +1100, Matthew <admin@stlsoft.dot.dot.dot.dot.org> wrote:
>>>>> 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.
>>>
>>> I don't see how showing someones past mistake (a matter of opinion,
>>> which I happen to share), has any bearing on another action which
>>> may/may not be a mistake (another matter of opinion).
>>>
>>> Yes, Walters motivation may be as stated, however, clearly he
>>> believes
>>> he is being true to that motivation WRT to the missing return
>>> situation, therefore "at best" Kris has shown that length was/is a
>>> bad idea and needs to be changed, but it has little or no bearing
>>> on
>>> the missing return situation.
>>
>> Well put. I just don't agree.
>
> Sorry, don't agree with what in particular?
> - Walter believes it's true to his motivation.
> - The behaviour is true to Walters motivation.
> - This argument has no bearing on the other.
>
>>>>> 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.
>>
>> Marvellous stuff. Keep going. I'm sure you've got one for every occasion, and it's ripping good sport.
>
> By defintion I have one for every instance in which someone appears to
> _me_ to be illogical.
> (I accept the posibility that I could be wrong and welcome a rebuttal)
>
>>> 1. You have chosen to attack the method in which I have presented
>>> my
>>> argument, instead of the actual argument itself:
>>
>> Well, it appears that you're more adept at quoting other's wisdoms,
>> than
>> acquiring your own.
>
> Now you're attacking me: http://www.datanation.com/fallacies/attack.htm
>
>> Specifically, I _did_ attack the argument, and the
>> proof of that is that you responded to my point. Doh!
>
> You attacked _both_ the argument _and_ the method in which it was
> proposed.
> The first is fine, the seccond is illogical.
>
>> Let's see what gnomic little nugget you're going to profer next ...
>
> The reason I profer these links is simple. In my experience a skillful writer/speaker can sway an audience to believe/disbelieve just about anything, they can do it without providing any logical or rational reasoning.
>
> These links helped _me_ understand what they were doing and why it was illogical, I hope to enlighten as many people as I can, so that we can all get on with having logical, rational debates with good sound reasoning.
>
> Now, I'm not saying either you or Kris _are_ illogical and/or irrational at all, you both exhibit very good logical and rational reasoning, however in this particular case I think the argument is illogical and I'm trying to explain why to the best of my ability.
>
> My intention is not to attack the person at all (for that would be illogical), however for some reason you seem to have taken it as an attack against the person, and attacked back in that fashion.
>
> I may be wrong about this argument being illogical. If you believe so please make an attempt to refute my argument in the same manner in which it was proferred, with logic.
Very well, put. What you either fail to recognise, or may recognise all too well, is that by contextualising both your own arguments and those of others in logic terms (I'd say logical terms, but that'd be confusing, illogical as that may be), you are attempting to coerce just as surely as those whom you (claim to) refute.
Indeed, examining your posts from a psychological perspective reveals all manner of interesting little tactics. For example, "please make an attempt to refute my argument in the same manner in which it was preferred, with logic". This not only attempts to (subconsciously) persuade the recipient (me) _and_ others to accept that my/Kris' arguments thus far are devoid of logic, it also inclines us all to treat your posts as logical because you explicitly and overtly put in your impressive links. Furthermore, it attempts to control the debate - in your favour no doubt - by prescribing its form.
I'm neither impressed with your tactics (though I recognise that they may well be effective in many of your online relationships), nor am I inclined to comply with your attempts to frame the debates according to your own terms.
|
February 08, 2005 Re: -release switch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | "Derek Parnell" <derek@psych.ward> wrote in message news:cu6noo$9a1$1@digitaldaemon.com... > On Mon, 7 Feb 2005 13:36:48 +1100, Matthew wrote: > >> "Derek Parnell" <derek@psych.ward> wrote in message news:cu66qc$29vn$1@digitaldaemon.com... >>> On Mon, 7 Feb 2005 09:32:19 +1100, Matthew wrote: >>> >>>> "sai" <sai_member@pathlink.com> wrote in message news:cu65me$27i4$1@digitaldaemon.com... >>>>> Anders_F_Bj=F6rklund?= says... >>>>>>Okay, so -release is "intuitive" and "self-explanatory" - but >>>>>>you'll >>>>>>have to read the docs to find out what it does ? Does not compute >>>>>>:-) >>>>>>I find "-debug -release" to be a rather weird combination of >>>>>>DFLAGS >>>>>>? >>>>> >>>>> Yes, -release means ..... it is a release version with all >>>>> contracts >>>>> (including >>>>> pre-conditions, invariants, post-conditions and assertions) etc >>>>> etc >>>>> turned off, >>>>> quite self explainatory to me !! >>>> >>>> I think the original issue under debate, sadly largely ignored >>>> since, >>>> is >>>> whether contracts (empty clauses elided, of course), should be >>>> included >>>> in a 'default' release build. I'm inexorably moving over to the >>>> opinion >>>> that they should, and I was hoping for opinions from people, >>>> considering >>>> the long-term desire to turn D into a major player in systems >>>> engineering >>> >>> I'm thinking as I write here, so I could be way off ... >>> >>> Isn't the idea of contracts just a mechanism to assist *coders* >>> locate >>> bugs >>> during testing. >> >> Well, yes and no. Yes, in the sense of a literal interpretation of >> that >> sentence. No in the sense that testing never ends - there is no >> non-trivial code that can be demonstrated to be fully tested! > > Of course. In the same sense that nothing is ever perfect. By > 'testing' I > was referring to the formal development process. Gotcha > And I was thinking more > about *who* was doing the testing (as a formal process). The contract > code, > as I see it, is designed to interact with a developer and not an end > user. Yes, that's a valid pov. For myself, I tend towards thinking of the contract between the software design and its reification in code (by fallible programmers), whose primary purpose is to protect the system on which it runs from damage. Sounds a bit calamitous, I know, but I've found that to be the most helpful, albeit a bit strict, perspective. >> As such, there's a strong argument that contracts should stay in. >> IMO, >> the only reasonable refutations of that argument are on performance >> grounds. > > 'stay in' what? The executable shipped to the end user? Most certainly. Since a contract violation indicates that the code is performing out of the bounds / against its design, that's something that needs to be detected and handled in all possible circumstances. (Naturally, that's a completely different thing from handling out of bounds runtime conditions.) > Well of course you > could, as in the end, its really a matter of style. I'm using the > model > that says that "contract code" is that portion of the source code that > is > only examining stuff so that it can detect specification errors. Other > sorts of errors, such as bad data, and such as (illogical?) situations > that > *have not been specified*, are being tested by different portions of > source > code at run-time. So its just a matter of definition, I guess. It is indeed. > I'm just segregating the types of errors being tested based on who > will be > getting the messages about said errors. "Contract" code assumes its > audience for its messages is the development team, "Other Error > Testing" > code assumes its audience for its messages is both development people > *and* > end users. From the perspective of who gets to see them, then I agree with what you say. Furthermore, I think it's a nice way of looking at it. Attractive as it is, however, I don't think it can be allowed to sway us into accepting that contracts should not manifest in the presence of users just because they're ill equipped to deal with the messages taht will be produced. Their prime purpose is to detect invalid programs, which must, axiomatically, be something that a user would not want to be executing on their system. More practically, I can say that from the experience of my recent work for a client - the project that has informed on / firmed up my commitment to 'CP-live' - that the users did indeed find it strange that the software informed them that it was invalid. However, when I (i) explained what this meant, and (ii) fixed the bug and had everything flying again with 10 minutes, they grok'ed it. Enthusiastically. > "Contract" code checks for bad output using good input, bad input > caused by > coding errors (i.e. not user entered data), illogical process flows, > etc... Yes. > "Other Error Testing" code checks for bad inputs, bad environments > (eg. > missing files), temporal anomalies (eg. a file which was open, is > suddenly > found to be closed), etc... Yes, although I would hazard to suggest that the latter (the unexpectedly closed) would more likely be a sign of a bug in most instances in which it might possibly happen. Now, if you meant unexpectedly deleted, that would be more a runtime error condition, rather than violation. >>> And by 'bugs', I mean behaviour that is not documented in >>> the program's (business) requirements specifications. As distinct >>> from >>> runtime handling of bad data or unexpected situations. >> >> Well, your terminology is a bit off. You say "distinct from runtime >> handling of bad data or unexpected situations", implying 'bad data' >> and >> 'unexpected situations' are kind of part of the same thing. > > Sorry. They are two (of many) distinct classes of errors. 'bad data' > is one > type of error. 'unexpected situations' is another type of error. Here is where we get woolled up on the terminology, I think. Bad data is unequivocally a runtime error condition. But 'unexpected situations' can be that, or it can be a contract violation, depending on circumstances. The (10 minute) violation of which I've spoken a couple of times was most certainly an unexpected situation - hence it fired the violation assert and killed the process. There were other 'unexpected conditions' that were, in a sense, not so unexpected, since they were catered for in the code. One or two of these did occur, even though we didn't expect them to, but because we'd accounted for them, they resulted in a graceful reset and restart of the offended communications channel. I think I'd have to say that 'unexpected situation' is too maleable a term to be meaningful. I see it in black-and-white: there are contract violations and there are runtime error conditions. The former detect violations of the design assumptions. The latter are part of the design. (It is in the cracks between the two where the nightmares occur. The only other bug in the system was not caught for a week because the invariant for the Channel class was insufficiently specific. Thus, this can be said to be a defficiency in the design of the contracts, just as much as it manifests as a bug in the code.) >> A lot of >> this depends on which term one wishes to use for what concept. Hence, >> one could argue that if a program encounters an 'unexpected >> situation', >> then it's operating counter to its design, and is invalid. > > I meant 'unexpected' in the sense that it is a situation that was not > documented in the requirements specification, but happened anyway. I > could > be seen as a bug in the spec, rather than the code. Between spec and code is design. If it was accounted for in the design, then the code should handle it. If not, violation! <G> >>> If so, then by the time you build a final production version of the application, all the testing is completed. >> >> As I said, this can never be asserted with 100% confidence. > > Again it's a definition thing. "testing is completed" means that the > formal > testing process for release candidate X is completed and the source > code > for that candidate is frozen. A production build is produced from that > and > a 'gold disk' created for the marketing/sales group. > > Of course, the test builds for the code still exist, but they are only > used > in house and by beta testers. > > But yes, I agree that end users are also involuntary gamma testers ;-) An excellent phrase! I shall quote you with gay abandon. <G> >>> And thus contracts can be >>> removed from the final release. >> >> So this conclusion may not be drawn. >> >>> However, you might keep them in for a beta >>> release. >> >> Most certainly. Again, if, for performance reasons, a decision is >> made >> on performance grounds. >> >>> Bad data and unexpected situations should be still addressed by >>> exceptions >>> and/or simple messages, designed to be read by an *end* user and not >>> only >>> the developers. >> >> Assuming that your unexpected situations are in the 'bad data' camp, rather than invariant violations, in which case: Yes. > > I'm thinking about the *cause* of invariant violations. When caused by > coding errors, then they should be tested for by contract code. When > caused > by inputting bad data, then they should be handled by non-contract > testing > code. By definition, a contract violation cannot be as a result of bad data. > I say this, just because I can conceive that some testing code is not > suitable for shipping to unsuspecting customers, and should really > just be > handled in-house. As can I. In the latest project - the only one in which I've really gone to town on C.P - there was a lot of code that was debug only. I wrote ACMECLIENT_ASSERT and ACMECLIENT_MESSAGE_ASSERT for the debugging stuff, and there was ACMECLIENT_ASSERT_PRECONDITION, ACMECLIENT_ASSERT_POSTCONDITION and ACMECLIENT_ASSERT_INVARIANT for the C.P. The presence/absence of the two sets were independent. In practice, we have everything in the debug build, and only the CP ones in release. > Such code needs to be removed from production versions > and the DMD -release switch is the current mechanism for doing that. Agreed. That's why I'm suggesting that we need : 1. Separate 'assertion' constructs for C.P., as opposed to debug/developer only assertions 2. To separation the elision/enabling of the two types. Specifically I suggest that assertions are in unless "-release" is specified, and but C.P. constructs are in unless "-nocontracts" is specified. However, I fear all this good stuff we've been covering in the last few days will falter because Walter may not want to, at this stage, introduce separate constructs for CP vs debug/developer assertions. Which, then, makes writing large system stuff in D harder, as Kris's been regretfully observing. Perhaps a solution is that "-nocontracts" elide all assertions within in/out/invariant blocks, and "-release" all those without. Walter? Cheers Matthew |
February 08, 2005 Re: -release switch | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew | I can also lament this; when people feel they've found a bug, they feel one of two things: anger, that there's a bug (most common in production) or satisfaction, for finding a mistake in someone else's work.
In fact, some of the second case of people will get noticeably dissapointed if you verify that what they experienced, for whatever reason, is NOT a bug - even if it's not their fault either (I remember remarking on this, but at the moment I can't think of how these two conditions can both be true.)
Anyway, if someone finds a bug and they get a warning describing something about what happened, they tend to be more often of the second class. Not only because the error tends to corrupt their data less (not transparently screwing up, but catching itself) but because it's definitely a bug. There's still often anger there, but there's usually satisfaction too.
But, next, if you have it fixed almost immediately after it's reported... well, let's be realistic:
Most end users know that many softwares they use have bugs. They've been frustrated by bugs in Windows, spyware (which often crashes Internet Explorer for them), and other even good software. There are always bugs, and so EVEN WHEN THEY DON'T FIND ANY, they expect them.
But, if they report a bug (which hopefully should be unlikely anyway) and it gets fast response, that's something else. Confidence. They knew there would be bugs before, but now, NOW they know that if they ever find one, they'll have an easy message to report, and once you get it you'll fix it for them and get them the new version. They will love you.
Maybe if we were back 20 years ago, we could try to fix this. But, it's too late now. We can't pretend bugs don't exist, or are so uncommon our clients won't expect them - even in OUR software. Nor can we pretend they won't, because... they will.
So, the trick is optimizing the solution. Making them trust us, you, again. At least, imho.
-[Unknown]
> More practically, I can say that from the experience of my recent work for a client - the project that has informed on / firmed up my commitment to 'CP-live' - that the users did indeed find it strange that the software informed them that it was invalid. However, when I (i) explained what this meant, and (ii) fixed the bug and had everything flying again with 10 minutes, they grok'ed it. Enthusiastically.
|
Copyright © 1999-2021 by the D Language Foundation