* Re: Critique of Ariane 5 paper (finally!) @ 1997-08-21 0:00 aek [not found] ` <33FC66AD.9A0799D4@calfp.co.uk> 0 siblings, 1 reply; 132+ messages in thread From: aek @ 1997-08-21 0:00 UTC (permalink / raw) In <dewar.872088939@merv> dewar@merv.cs.nyu.edu (Robert Dewar) wrote: >In this particular case, the very reasonable point that DBC may be a useful >tool in helping to achieve reliability in some circumstances ^^^^^^^^^^^^^^^^^^^^^ This is the point. When one claims that some new method or tool may be useful in some circumstances he seems to be obliged to describe those circumstances more or less precisely. But if one claims that this new method or tool is very useful universally then he frees himself from this trouble and invites other people to do this job. Alexander Kopilovitch aek@vib.usr.pu.ru Saint-Petersburg Russia \x1a -------------------==== Posted via Deja News ====----------------------- http://www.dejanews.com/ Search, Read, Post to Usenet ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <33FC66AD.9A0799D4@calfp.co.uk>]
* Re: Critique of Ariane 5 paper (finally!) [not found] ` <33FC66AD.9A0799D4@calfp.co.uk> @ 1997-08-22 0:00 ` Robert S. White 1997-08-22 0:00 ` Samuel Mize 1997-08-23 0:00 ` Ken Garlington [not found] ` <33FFA4B1.3543@flash.net> 1 sibling, 2 replies; 132+ messages in thread From: Robert S. White @ 1997-08-22 0:00 UTC (permalink / raw) In article <33FC66AD.9A0799D4@calfp.co.uk>, nickle@calfp.co.uk says... >Let us say for the moment that in some circumstances DBC helps. >For those that have been critising DBC, since DBC is optional, and is an ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Nobody that I know of on this thread has been "critising DBC"! What all the furor is about, is the claims that DBC _must_ be used to create reliable software. Ken, myself, and a few others have been arguing that you can not always employ the executable code aspects of DBC (or Ada run time checks) in hard real time systems with constrained resources. The other issue is that in the Ariane 5 case, the methodology that was in place (system requirements review and software requirements specification), was not followed adequately. To quote the inquiry report once more: "the overriding means of preventing failures are the reviews which are an integral part of the design and qualification process, and which are carried out at all levels and involve all major partners in the project (as well as external experts)" The Ariane 4 IRS software as-is reuse should not have made it by such reviews. Please read Ken's rebuttal paper: http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/ My reading of it does not indicate a general "critising DBC" but rather it summerizes: "In the specific case of the Ariane IRS design fault, there is not clear and compelling evidence that DBC/Eiffel assertions were likely to have uncovered the fault prior to operational use, either through their documentation, test, or execution value. Furthermore, alternative means were available to the Ariane team to isolate the particular fault, even without the use of DBC/Eiffel. Therefore, although there may be a compelling claim to use DBC/Eiffel in real-time safety-critical systems, the Ariane case (and the Eiffel paper describing this case) does not support such a claim." My complaint is against the claim in the Eiffel paper: "Does this mean that the [Ariane 5] crash would automatically have been avoided had the mission used a language and method supporting built-in assertions and Design by Contract? Although it is always risky to draw such after-the-fact conclusions, the answer is probably yes..." ^^^^^^^^^^^^ I say, IMO, probably no for the Ariane 5 case. But I think it is a "good thing" to use assertions and/or a DBC methodology whenever practical. Unfortunately, IME, it is often not practical for resource constrained hard real time systems. _____________________________________________________________________ Robert S. White -- An embedded systems software engineer ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Critique of Ariane 5 paper (finally!) 1997-08-22 0:00 ` Robert S. White @ 1997-08-22 0:00 ` Samuel Mize 1997-08-22 0:00 ` Samuel Mize 1997-08-23 0:00 ` Ken Garlington 1 sibling, 1 reply; 132+ messages in thread From: Samuel Mize @ 1997-08-22 0:00 UTC (permalink / raw) Robert S. White wrote: > The other issue is that in the Ariane 5 case, the > methodology that was in place (system requirements review and > software requirements specification), was not followed > adequately. To quote the inquiry report once more: ... > My complaint is against the claim in the Eiffel paper: > > "Does this mean that the [Ariane 5] crash would > automatically have been avoided had the mission used > a language and method supporting built-in assertions > and Design by Contract? Although it is always risky > to draw such after-the-fact conclusions, the answer > is probably yes..." > ^^^^^^^^^^^^ > > I say, IMO, probably no for the Ariane 5 case. I'd even tolerate the "probably yes," if it weren't explicitly stated that DBC is the ONLY method that would probably have avoided the crash. No discussion about whether DBC would have helped is relevant to my point. I concede that DBC is one method that would have helped. I'll say that again: I CONCEDE THAT DBC WOULD PROBABLY HAVE HELPED, IF ONLY BECAUSE IT ISN'T DBC WITHOUT REVIEWS AND TEST. But the paper says that ONLY DBC would have helped, as I'll show below. If the authors had said "Yes, the claim was too strong, sorry," a lot of us would have shut up and gone away. Co-author Jean-Marc Jezequel has said that this does not characterize what the paper was MEANT to say. I have little dispute with what he says they MEANT to say[1]: Let's finally sum up what I perceive as the most important claims in this paper: - reusing a component without checking its full specification is dangerous, which means that simple minded CORBA-like approaches at building components for mission-critical software are doomed. - using design by contract is an interesting way to specify the behavior of a component - at least in the case of Ariane 501, simple assertions (a la Eiffel and other languages) would have been expressive enough to specify the fatal hidden assumption. But the paper DOES state explicitly that DBC is the ONLY method that would have avoided the crash, and that existing methods were applied but did not succeed. Following are my reasons for stating that the paper says this. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THE PAPER CLAIMS THAT ARIANE 5 APPLIED ALL RELEVANT EXISTING METHODS At the very least it strongly implies this. From the paper: The ESA's software people knew what they were doing and applied widely accepted industry practices. No, the project made an explicit decision to NOT apply widely accepted industry practices. I have yet to see any support for this assertion: not in the Eiffel paper, not in the ESA report, not in the net traffic. From the paper: Is it a testing error? Not really. ... But if one can test more one cannot test all. Testing, we all know, can show the presence of errors, not their absence. This implies that the error in question would not likely have been found through normal testing. Yet it is, in fact, one that would have blown out a normal test scenario the first time they tried it. The addition of DBC would have made no more difference than would the addition of paper hats. There may indeed be errors that cannot be found through testing, and that DBC would find, but this is NOT demonstrated by the Ariane 5 case. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - THE PAPER CLAIMS THAT ONLY DBC WOULD HAVE PREVENTED THIS ERROR The concluding section, labelled "The lesson for every software developer," is clearly meant to state what the Ariane 5 crash shows. It states: To attempt to reuse software without Eiffel-like assertions is to invite failures of potentially disastrous consequences. ... For reuse to be effective, Design by Contract is a requirement. Without a precise specification attached to each reusable component -- precondition, postcondition, invariant -- no one can trust a supposedly reusable component. This says that, if a reused component has not been analyzed with DBC, you cannot trust it, and you are inviting failure. No other method is sufficient, by this statement. From the paper: Reuse without a contract is sheer folly. Does this state that Ariane 5 would have crashed, no matter what other methods were used, unless DBC were also used? In context, yes. It's from the conclusions section, "The lesson for every software developer." Surely this is meant to be the lesson of the Ariane 5 crash. Surely "contract" in this context is intended to refer specifically to a Design By Contract artifact. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [1] I'd dispute his first point if "full specification" is limited to pre/post conditions and invariants. In some cases these are too little, in others they may not be needed. However, it's certainly failure-prone to reuse components without reviewing their specs and designs. I know too little about CORBA to have an opinion on its (in)sufficiency. Sam Mize ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Critique of Ariane 5 paper (finally!) 1997-08-22 0:00 ` Samuel Mize @ 1997-08-22 0:00 ` Samuel Mize 0 siblings, 0 replies; 132+ messages in thread From: Samuel Mize @ 1997-08-22 0:00 UTC (permalink / raw) Samuel Mize wrote: > Co-author Jean-Marc Jezequel has said that this does not > characterize what the paper was MEANT to say. I have > little dispute with what he says they MEANT to say[1]: ... > [1] I'd dispute his first point if ... This footnote looks like a reference. I apologize for the inclarity. I should have referenced the text. According to Deja News, Mr. Jezequel posted this statement on 1997/03/18 to comp.lang.eiffel, comp.object, comp.software-eng, comp.programming.threads, comp.lang.ada, and comp.lang.java.tech. Sam Mize ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Critique of Ariane 5 paper (finally!) 1997-08-22 0:00 ` Robert S. White 1997-08-22 0:00 ` Samuel Mize @ 1997-08-23 0:00 ` Ken Garlington 1 sibling, 0 replies; 132+ messages in thread From: Ken Garlington @ 1997-08-23 0:00 UTC (permalink / raw) Robert S. White wrote: > > The Ariane 4 IRS software as-is reuse should not have made it > by such reviews. Please read Ken's rebuttal paper: > > http://www.progsoc.uts.edu.au/~geldridg/eiffel/ariane/ > > My reading of it does not indicate a general "critising DBC" > but rather it summerizes: > > "In the specific case of the Ariane IRS design fault, there > is not clear and compelling evidence that DBC/Eiffel > assertions were likely to have uncovered the fault prior to > operational use, either through their documentation, test, > or execution value. Furthermore, alternative means were > available to the Ariane team to isolate the particular > fault, even without the use of DBC/Eiffel. Therefore, > although there may be a compelling claim to use DBC/Eiffel > in real-time safety-critical systems, the Ariane case > (and the Eiffel paper describing this case) does not > support such a claim." In addition, it states in section 6: "It would not be appropriate to use the criticisms here to say in the general case that assertions have no value, anywhere ("casuistry"), but this criticism does not attempt to do this. It focuses on the specific claim in the Eiffel paper in the context of the Ariane IRS fault.... "Several Eiffel advocates will attest that they like the use of Eiffel for their domain. Eiffel may be very useful in some domains, however Ariane is a real-time embedded safety-critical system and has unique properties (as described above). Again, this is a specific, not a general, criticism of DBC/Eiffel." Perhaps my paper is so boring that no one made it to this section :) ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <33FFA4B1.3543@flash.net>]
* Re: Critique of Ariane 5 paper (finally!) [not found] ` <33FFA4B1.3543@flash.net> @ 1997-08-26 0:00 ` Nick Leaton [not found] ` <3403940F.4154@pseserv3.fw.hac.com> [not found] ` <3406BEF7.2FC3@flash.net> 0 siblings, 2 replies; 132+ messages in thread From: Nick Leaton @ 1997-08-26 0:00 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 8512 bytes --] Ken Garlington wrote: > > Nick Leaton wrote: > > > > Let us say for the moment that in some circumstances DBC helps. > > For those that have been critising DBC, since DBC is optional, and is an > > addition to the current methodology I think the only valid criticism one > > make, is if you can find a situation where DBC causes a problem. > > > > That is, where does DBC screw up, and the current methodologies do not. > > See my Ariane paper for some examples of such information: > > http://www.flash.net/~kennieg/ariane.html#s3.1.6 QUOTE ----------------------------------------------------------- 3.1.6 Adverse effects of documenting assertions There is a line of reasoning that says, "Even if DBC/assertions would have been of minimal use, why not include them anyway just in case they do some good?" Such a statement assumes there are no adverse impacts to including assertions in code for documentation purposes. However, there are always adverse effects to including additional code: As with any other project, there are management pressures to meet cost and schedule drivers. Additional effort, therefore, is discouraged unless justified. More importantly, all projects have finite time and other resources available. Time spent on writing and analyzing assertions is time not spent elsewhere. If the work that is not performed as a result would have been more valuable (in terms of its effect on the safety and integrity of the system) than the time spent with assertions, then the resulting system may be less safe. There is a growing consensus in the safety-critical software field that simpler software tends to be safer software [21]. With this philosophy, additional code such as assertions should only be added where there is a clear benefit to the overall safety of the particular system being developed. END QUOTE -------------------------------------------------------- 1) Additional effort. There is plenty of evidence that the cost of finding and fixing a bug early in the development process is much cheaper that fixing it later. Now *IF* DBC as a methodology produces earlier detection of faults, then this 'additional effort' is justified, as it is effort early in the development process. I believe this to be the case from practical experience. Developing code last week I detected errors in my code very early, even though the fault would have only shown itself in an exception. I had an invariant that made sure I had an error handler in a class. It broke as soon as I tried to construct the class, it didn't wait until I tried to generate an error, all because I hadn't set the handler up. That combined with permantant testing of assertions has the effect of producing less effort. 2) Time spent else where. Is this the case? Some of it may be, but I believe if you cannot be rigourous about what your software is trying to do, by writing assertions, then you are unlikely to produce a quality system. The effect of writing assertions overlaps with the design process. It is not wasted time, it just comes under a different heading. If your design process listed the assertions in the specification, would implementing them be a waste of effort? 3) Simple software. You bet. The simpler the better. Occams Razor rules. Now here there is a split between DBC a la Eiffel and DBC, say in C++. In Eiffel it is simple. In C++ it is hard, particularly with inheritance of assertions. One common theme from Eiffel practitioners is their support for DBC. Why? They are simple to write. Prior to using Eiffel I had read about the language. I was extremely sceptical about assertions because in my experience with C++ and C++ programmers, no one writes them, mainly because it is hassle. Take away the hassle and people will write them because of the benefits. > http://www.flash.net/~kennieg/ariane.html#s3.2.2 QUOTE -------------------------------------------------------- 3.2.2 Adverse effects of testing with assertions Assume for a moment that the proper testing environment and data had been available. Putting aside for the moment the question as to whether assertions would have been necessary to detect the fault (see section 4.2), are there any disadvantages to using assertions during testing, then disabling them for the operational system? In the author's experience, there are some concerns about using this approach for safety-critical systems: The addition of code at the object level obviously affects the time it takes for an object to complete execution. Particularly for real-time systems (such as the Ariane IRS), differences in timing between the system being tested and the operational system may cause timing faults, such as race conditions or deadlock, to go undetected. Such timing faults are serious failures in real-time systems, and a test which is hindered from detected them loses some of its effectiveness. In addition, the differences in object code between the tested and operational systems raise the issue of errors in the object code for the operational system. Such errors are most likely to occur due to an error in the compilation environment, although it is possible that other factors, such as human error (e.g. specifying the wrong version of a file when the code is recompiled) can be involved. For example, the author has documented cases where Ada compilers generate the correct code when exceptions are not suppressed, but generate incorrect code (beyond the language's definition of "erroneous") when they are suppressed. This is not entirely unexpected; given the number of user-selectable options present with most compilation environments, it is difficult if not impossible to perform adequate toolset testing over all combinations of options. Nothing in the Eiffel paper indicates that Eiffel compilers are any better (or worse) than other compilers in this area. Although this is a fault of the implementation, not the language or methodology, it is nonetheless a practical limitation for safety-critical systems, where one object code error can have devastating results. One possible approach to resolving this issue is to completely test the system twice; once with assertions on and another time with assertions suppressed. However, the adverse factors described in section 3.1.6 then come into play: By adding to the test time in this manner, other useful test techniques (which might have greater value) are not performed. Generally, it is difficult to completely test such systems once, never mind twice! This effect is worse for safety-critical systems that perform object-code branch coverage testing, since this testing is completely invalidated when the object code changes [25]. Overall, there are significant limitations to using this technique for safety-critical systems, and in particular real-time systems such as the Ariane 5 IRS. END QUOTE -------------------------------------------------------- Assertions affect timing in safety critical systems. Firstly it depends on the implementation. It is easy to envisage a system where the assertions are redundantly executed. But you would only want to do that if you were running with faulty software ?!*^�% I also find it worrying that systems are being used for safety critical apps where there is the possibility of a race or deadlock to occur. Compilation problems. These can occur in any system as you are aware. From discussions with some of the people involved in writting Eiffel compilers, the enabling, disabling of assertions has a very trivial implementation, which is very unlikely to go wrong. It has also be extensively tested in the field by end users. Do you trust your compiler? If not, you shouldn't be writing safety critical software with it. Period. Next I find some of the logic of your arguments here very weak. Paraphrasing. We have trouble testing safety critical systems, but we will use them anyway. Hmmm. > http://www.flash.net/~kennieg/ariane.html#s3.3 > > There are approaches that can avoid such costs, particularly those of > 3.2.2 and 3.3 (by not requiring object code modification). 3.1.6 can > be mitigated through the use of techniques that minimize cost (e.g. > automated structural testing analysis). > > > > > -- > > > > Nick -- Nick ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <3403940F.4154@pseserv3.fw.hac.com>]
* Re: Design By Contract [not found] ` <3403940F.4154@pseserv3.fw.hac.com> @ 1997-08-27 0:00 ` Ted Velkoff [not found] ` <5u3c6v$gtf$2@miranda.gmrc.gecm.com> [not found] ` <JSA.97Aug27180328@alexandria.organon.com> [not found] ` <EFM140.Fy9@syd.csa.com.au> [not found] ` <349224633wnr@eiffel.demon.co.uk> 2 siblings, 2 replies; 132+ messages in thread From: Ted Velkoff @ 1997-08-27 0:00 UTC (permalink / raw) W. Wesley Groleau x4923 wrote: > > Question for anyone who _really_ knows both Eiffel and Ada: > Suppose Ada added Eiffel assertions and Eiffel added separate > compilation of specs. Or even some sort of automated control that > prevented changing contract without special privilege. > > What remaining feature of either language (or both) would be a > significant advantage over the other and why? > In no particular order I offer my view of the remaining differences. To the best of my ability I've responded with reason and judgement :-) Concurrency. Ada's tasking is certainly more mature and tested in fielded products. There has been a lot of research done into concurrency in Ada that benefited Ada95. I personally find the SCOOP approach to concurrency proposed for Eiffel to be quite elegant from the standpoint of the ordinary programmer building a concurrent system. I think the jury's still out on how well it can be implemented. There are some important issues (like priority inversion, rate-monotonic scheduling, etc., among many others) that need to be addressed in order to be applied to the some of the kinds of systems that have been done in Ada. Constrained genericity. Constrained genericity is achieved in Ada typically by adding generic function or procedure parameters to the parameter list. Depending on the generic type, that list of parameters could be long. I think the Eiffel approach, which says an actual parameter must conform to (i.e. inherit from) some class, is simple and powerful, and typically results in shorter parameter lists. Multiple inheritance. I've read the section on multiple inheritance in the Ada95 Rationale several times and I confess I have never been able to understand the 2nd or 3rd examples. At the very least, it appears that just emulating multiple inheritance in Ada95 is hard. Of course the religious question is whether you believe in MI or not. After not being sure for about a year, I've come to believe it is extremely useful. I think Bertrand Meyer is correct in saying that MI is not bad as long as it is implemented properly. Using MI in Eiffel is really just no big deal. Dynamic binding. Someone please correct me if I'm wrong on this one, but I think in Ada95, the programmer has to designate whether dynamic binding can be applied by making a type "classwide" with 'Class. I think this is comparable to C++ "virtual", but I think I read that the Ada compiler is supposed to figure out which classwide calls are actually static in an executable. The chief objection (if I have understood the Ada mechanism correctly) might be that one might forget to make a type classwide that a descendant would need to override, and require a change to the code. In Eiffel, dynamic binding is the default. The programmer has to do something special ("frozen") to make it impossible for descendants to redefine. Garbage collection. There are many applications being done in Ada for which garbage collection is not appropriate (hard real-time, etc.). I suspect that there are many more applications being done in Ada that could benefit from garbage collection. Eiffel is of course garbage collected. There are also library facilities for fine-grained control during execution. Exception handling. Ada is fairly permissive with exceptions. (Meyer has written about this in several places.) The bad things that I have done and seen done in Ada are to use exceptions as gotos, and sweep problems under the rug. Eiffel is much more restrictive about what can be done in response to exceptions. It significantly reduces the chances of programmers doing these sorts of things. Tool environments. Articles have appeared in Ada Letters that questioned the wisdom of incorporating inheritance into Ada95, based on the fact that comprehension of a class interface requires manually finding and traversing the set of ancestors. This problem is of course not unique to Ada. As far as I know, Eiffel environments are the only I know of that support class flattening (i.e. generating the union of all features of all ancestors). They also support push-button access to the list of clients, suppliers, ancestors, descendants. I don't know how many times in other languages (including Ada) I have really needed to find out "who's calling this?" and had nothing better at my disposal than grep. Of course these are not language issues - I'd love to see vendors of Ada products add these kinds of capabilities. Child packages. At a minimum, the rules about child packages are complicated. I'm personally unconvinced by the examples in the Ada95 Rationale for their use. In particular, the example of complex numbers seems to be more properly addressed by inheritance (i.e. tagged types). I would worry that programmers using that as a guide would attempt to solve many problems with child packages that should use inheritance instead. Pointers to functions, aliases. I sort of got the heeby-jeebies when I saw these introduced into Ada95. They didn't appear any easier or safer to use than their counterparts in C/C++. In Ada83, you could sort of see the argument for subprogram pointers, but once inheritance and abstract subprograms were introduced, they seemed out of context to me. Eiffel doesn't have these things since they are tricky to use and jeopardize reliability. -- Ted Velkoff ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <5u3c6v$gtf$2@miranda.gmrc.gecm.com>]
* Re: Design By Contract [not found] ` <5u3c6v$gtf$2@miranda.gmrc.gecm.com> @ 1997-08-28 0:00 ` Patrick Doyle 1997-09-06 0:00 ` Joachim Durchholz [not found] ` <34058808.3BF@pseserv3.fw.hac.com> 1 sibling, 1 reply; 132+ messages in thread From: Patrick Doyle @ 1997-08-28 0:00 UTC (permalink / raw) In article <5u3c6v$gtf$2@miranda.gmrc.gecm.com>, Paul Johnson <paul.johnson@gecm.com> wrote: >In article <3403C44F.2424@erols.com>, velkoff@erols.com says... > >[In the middle of an otherwise good posting] > >> In Eiffel, dynamic binding is the default. The programmer has >>to do something special ("frozen") to make it impossible for descendants >>to redefine. > >I've seen this mistake made a few times around the net. The assumption is >that "frozen" was introduced as a sort of "anti-virtual", or at least that >it has this effect. [Discussion of difference between dynamicity and redefinability] >The correct answer is "2". The dynamic binding still happens. The only >effect of "frozen" is that if I create a new descendant of "B", I cannot >redefine "foo" in it. > >Dynamic binding and "frozen" are orthogonal issues. Now, have a look at the quote you took, and tell me how it contradicts this. -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-28 0:00 ` Patrick Doyle @ 1997-09-06 0:00 ` Joachim Durchholz 1997-09-06 0:00 ` Patrick Doyle 0 siblings, 1 reply; 132+ messages in thread From: Joachim Durchholz @ 1997-09-06 0:00 UTC (permalink / raw) Patrick Doyle wrote: > >Dynamic binding and "frozen" are orthogonal issues. > > Now, have a look at the quote you took, and tell me how it > contradicts this. Nonvirtual C++ functions and frozen Eiffel routines are not the same. 1) Even a frozen routine can be polymorphic - it may itself override an inherited routine. (This is not an issue for the frozen features declared in ANY, PLATFORM or GENERAL.) 2) There is no way in Eiffel to achieve the effect of C++ nonvirtual member functions. If you have a routine blah (x: A_CLASS) is do x.do_something end the standard C++ policy (nonvirtual routine) would be to always call A_CLASS.do_something, regardless of wether the parameter passed in for x is of that type or of a descendant. In Eiffel, the decision which routine to call will always be based on the run-time type of x, *never* on the declared type along. (Of course, if do_something is frozen in A_CLASS, no polymorphism is possible, so the compiler should optimize this to a static call. But that's the same as when the compiler determines that only A_CLASS objects will be passed for x in the given program.) Regards, Joachim -- Please don't send unsolicited ads. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-06 0:00 ` Joachim Durchholz @ 1997-09-06 0:00 ` Patrick Doyle 0 siblings, 0 replies; 132+ messages in thread From: Patrick Doyle @ 1997-09-06 0:00 UTC (permalink / raw) In article <34108452.BAF03BA5@munich.netsurf.de>, Joachim Durchholz <joachim.durchholz@munich.netsurf.de> wrote: >Patrick Doyle wrote: >> >Dynamic binding and "frozen" are orthogonal issues. >> >> Now, have a look at the quote you took, and tell me how it >> contradicts this. > >Nonvirtual C++ functions and frozen Eiffel routines are not the same. I don't disagree with this. My point is that what you quoted did not claim they were the same. However, you've removed the quote and my mail reader no longer has the original, so I can't explain further. -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <34058808.3BF@pseserv3.fw.hac.com>]
* Re: Design By Contract [not found] ` <34058808.3BF@pseserv3.fw.hac.com> @ 1997-08-28 0:00 ` Darren New 0 siblings, 0 replies; 132+ messages in thread From: Darren New @ 1997-08-28 0:00 UTC (permalink / raw) In article <34058808.3BF@pseserv3.fw.hac.com>, W. Wesley Groleau x4923 <wwgrol@pseserv3.fw.hac.com> wrote: >Paul Johnson wrote: >> Now in my code I have something like: >> >> a: A; >> b: B; > >Is this legal Eiffel? If so, put case insensitivity on the list of >Ada's advantages. > >Unless Eiffel demands upper case for types/classes and lower case >for variables/constants. In that case, it's even, i.e., the >distinction introduces some benefits but also some problems. Uh, no. That's not the point. In Eiffel, there's certain syntactic places the name of a class can appear, and certain syntactic places the name of a variable can appear, and the two don't overlap. Hence, the case distinction is irrelevant. This is like saying in C struct x { struct x * next; int data; } struct x next; [...] next = next->next; Now, granted, in this case it's probably bad style, but there's no confusion that the first two "next" references are to the variable and the third is to the structure member. Same idea in the Eiffel code. ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <JSA.97Aug27180328@alexandria.organon.com>]
* Re: Design By Contract [not found] ` <JSA.97Aug27180328@alexandria.organon.com> @ 1997-08-28 0:00 ` W. Wesley Groleau x4923 1997-09-03 0:00 ` Don Harrison 1 sibling, 0 replies; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-08-28 0:00 UTC (permalink / raw) Jon S Anthony wrote: > > In article <3403C44F.2424@erols.com> Ted Velkoff <velkoff@erols.com> writes: > > > Constrained genericity. > > Constrained genericity is achieved in Ada typically by adding > > generic function or procedure parameters to the parameter list. > > Depending on the generic type, that list of parameters could be long. > > I think the Eiffel approach, which says an actual parameter must > > conform to (i.e. inherit from) some class, is simple and powerful, and > > typically results in shorter parameter lists. > > That's not quite right. The Ada approach basically subsumes the > Eiffel approach: an actual must conform/inherit from some class or you > can use an approach sort of like what you mention. Also, in the > latter case, the parameter lists can be captured in a signature > package which can then be passed as a single parameter to another > generic. > > > Of course the religious question is whether you believe in MI or > > not. > > Right. > > > After not being sure for about a year, I've come to believe it is > > extremely useful. I think Bertrand Meyer is correct in saying that MI > > Somewhat interestingly, I (and some others here) went the other way > 'round and now consider MI to be (generally speaking) poor modeling. > > > is not bad as long as it is implemented properly. Using MI in > > Eiffel is really just no big deal. > > It makes it at least "reasonable" - but it does not address the > modeling issue. > > > Dynamic binding. > > Someone please correct me if I'm wrong on this one, but I think > > in Ada95, the programmer has to designate whether dynamic binding can be > > applied by making a type "classwide" with 'Class. I think this is > > A dynamic binding can be applied to primitive operations of "tagged" > types. _Whether_ any given _invocation_ of such an operation will be > so treated requires that the actual involved be classwide. So, all > primitive ops of tagged types are dispatchable, but if you can control > for any given call instance whether you really want that to happen > > > comparable to C++ "virtual", but I think I read that the Ada compiler is > > Not like C++ "virtual". In C++ only operations tagged with "virtual" > can be dispatching and this tagging happens at the point they are > _declared_. In Ada, all primitive ops of tagged types are > dispatching. > > > executable. The chief objection (if I have understood the Ada mechanism > > correctly) might be that one might forget to make a type classwide that > > a descendant would need to override, and require a change to the code. > > This is indeed a problem with C++ "virtual" but has nothing to do with > Ada. > > > Garbage collection. > > There are many applications being done in Ada for which garbage > > collection is not appropriate (hard real-time, etc.). I suspect that > > there are many more applications being done in Ada that could benefit > > from garbage collection. > > Absolutely. > > > Eiffel is of course garbage collected. There are also library > > facilities for fine-grained control during execution. > > Right. > > > Exception handling. > > This actually seems to be another religious issue. > > > to Ada. As far as I know, Eiffel environments are the only I know of > > that support class flattening (i.e. generating the union of all features > > of all ancestors). > > I seem to recall some freeware stuff that can do this for any language > with class based heirarchy. If anyone actually cares, I think I can > dig this up... > > > They also support push-button access to the list of clients, > > suppliers, ancestors, descendants. I don't know how many times in > > other languages (including Ada) I have really needed to find out > > "who's calling this?" and had nothing better at my disposal than > > grep. > > Such tools certainly do exist. Emacs ada-mode does much of this. > Other environments pretty much do it all and then some. > > > more properly addressed by inheritance (i.e. tagged types). I would > > worry that programmers using that as a guide would attempt to solve many > > problems with child packages that should use inheritance instead. > > Or vice-versa. I'm no longer a big fan of class-based inheritance. > It is useful and has its place. But like anything else - it is a poor > choice for "universal" application. > > > Pointers to functions, aliases. > > I sort of got the heeby-jeebies when I saw these introduced > > into Ada95. They didn't appear any easier or safer to use than > > their counterparts in C/C++. In Ada83, you could sort of see the > > argument for subprogram pointers, but once inheritance and abstract > > subprograms were introduced, they seemed out of context to me. > > These things do have their ups and downs. To be fair, the way they > are done in Ada, probably the "worst" thing about them is they look > "ugly" - makes it look like you are cheating or up to something > nefarious. Note that no matter what, you kind of need subprogram > pointers to be a "good citizen" in today's C dominated world. They are _certainly_ safer than in C. Ada ensures conformance of parameter profiles and being in scope. It is true (as evidenced by the number of "why doesn't this work?" posts on the subject) that they are not easier to use than in C, but that is a side-effect of the safety rules. Inheritance, abstract subprograms, generic subprog params can substitute for subprog pointers, but not sometimes in a less readable and/or less efficient way, and sometimes not at all (as with the X11 & C callback paradigm). -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract [not found] ` <JSA.97Aug27180328@alexandria.organon.com> 1997-08-28 0:00 ` W. Wesley Groleau x4923 @ 1997-09-03 0:00 ` Don Harrison 1997-09-03 0:00 ` Jon S Anthony 1 sibling, 1 reply; 132+ messages in thread From: Don Harrison @ 1997-09-03 0:00 UTC (permalink / raw) Jon S Anthony wrote: :OTOH, Ada has no system validity problems. System validity, in its broadest sense, means that all usage of entities (variables) in a system is legal for all possible objects/values that can become attached (assigned) to them at runtime. This definition includes, but is not limited to, what is traditionally regarded as polymorphic usage. While Eiffel currently fails WRT polymorphic usage, Ada fails WRT other usage. See Deja News for details. So, your claim that Ada doesn't have system validity problems is false. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-03 0:00 ` Don Harrison @ 1997-09-03 0:00 ` Jon S Anthony 1997-09-04 0:00 ` Don Harrison 0 siblings, 1 reply; 132+ messages in thread From: Jon S Anthony @ 1997-09-03 0:00 UTC (permalink / raw) In article <EFx966.8LB@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > System validity, in its broadest sense, means that all usage of entities Well, you can define it anyway you wish, I suppose, but I was simply refering to its "traditional" usage vis-a-vis Eiffel. > While Eiffel currently fails WRT polymorphic usage, Ada fails WRT other > usage. See Deja News for details. > > So, your claim that Ada doesn't have system validity problems is false. As I recall, that scenario required the _concious_ and _explicit_ choice to violate certain aspects via Unchecked_Conversion. Not at all the same as the concealed land mines of Eiffel. But, I'm not going to say these are somehow ultra-bad or something. In practice they are probably not that big of a deal if you are aware and careful to avoid the situations. Besides, you snipped the one of two smileys I had in there... /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-03 0:00 ` Jon S Anthony @ 1997-09-04 0:00 ` Don Harrison 0 siblings, 0 replies; 132+ messages in thread From: Don Harrison @ 1997-09-04 0:00 UTC (permalink / raw) Jon S Anthony wrote: :In article <EFx966.8LB@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: : :> System validity, in its broadest sense, means that all usage of entities : :Well, you can define it anyway you wish, I suppose, but I was simply :refering to its "traditional" usage vis-a-vis Eiffel. Sure. :> While Eiffel currently fails WRT polymorphic usage, Ada fails WRT other :> usage. See Deja News for details. :> :> So, your claim that Ada doesn't have system validity problems is false. : :As I recall, that scenario required the _concious_ and _explicit_ :choice to violate certain aspects via Unchecked_Conversion. No, I'm not referring to Unchecked_Conversion. As we both know, all bets are off when you choose to do naughty things. I recall we agreed that neither Ada nor Eiffel stopped you statically from trying to attach an out-of-range value at runtime - for Ada, to a subtype; for Eiffel to a precondition-constrained type. However, I recall Norman Cohen (I think) volunteering a hole in Ada's type system - don't remember the details, though. BTW, where is Norm these days? Haven't seen him in c.l.a. lately. :Not at all the same as the concealed land mines of Eiffel. But, I'm not :going to say these are somehow ultra-bad or something. In practice :they are probably not that big of a deal if you are aware and careful :to avoid the situations. Quite true. Essentialy, being able to break polymorphism isn't any worse than the uncertainty of not knowing whether a precondition will always be satisfied. It can justifiably be regarded as a variant of just that. There's no question, of course, that it would be preferable to exclude such errors statically, rather than having to deal with them dynamically. :Besides, you snipped the one of two smileys :I had in there... True. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <EFM140.Fy9@syd.csa.com.au>]
* Re: Design By Contract [not found] ` <EFM140.Fy9@syd.csa.com.au> @ 1997-08-28 0:00 ` Jon S Anthony 1997-08-29 0:00 ` Patrick Doyle 1997-08-29 0:00 ` Don Harrison 1997-08-28 0:00 ` Robert Dewar 1 sibling, 2 replies; 132+ messages in thread From: Jon S Anthony @ 1997-08-28 0:00 UTC (permalink / raw) In article <EFM140.Fy9@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > - Strict enforcement of encapsulation while maximising visibility. Eiffel > offers a look-but-don't-touch view of object attributes. In Ada83, > an attribute and its type has to be declared in the visible interface in > order for clients to see it's structure but then they can also update it > directly. If you declare its type as private, clients can't update it > directly but neither can they see its structure. Isn't that exactly the point? Why should a client be able to see the actual structure, aka implementation???? > - Simplicity which enables developers to focus on designing rather than > trying to remember language rules. A simplistic macroscopic comparison > of Eiffel and Ada based on the number of validity rules suggests that > Eiffel is about 50 times simpler than Ada. IMO, this is obviously one of those "yes it is, no it isn't" sort of things. It would be very difficult to get a _consistent_ objective metric for this. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-28 0:00 ` Jon S Anthony @ 1997-08-29 0:00 ` Patrick Doyle 1997-08-29 0:00 ` Jon S Anthony 1997-08-29 0:00 ` Don Harrison 1 sibling, 1 reply; 132+ messages in thread From: Patrick Doyle @ 1997-08-29 0:00 UTC (permalink / raw) In article <JSA.97Aug28172900@alexandria.organon.com>, Jon S Anthony <jsa@alexandria.organon.com> wrote: >In article <EFM140.Fy9@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > >> - Strict enforcement of encapsulation while maximising visibility. Eiffel >> offers a look-but-don't-touch view of object attributes. In Ada83, >> an attribute and its type has to be declared in the visible interface in >> order for clients to see it's structure but then they can also update it >> directly. If you declare its type as private, clients can't update it >> directly but neither can they see its structure. > >Isn't that exactly the point? Why should a client be able to see the >actual structure, aka implementation???? If you mean that Eiffel is letting the structure leak out by providing access to data members, then that's not true. The Eiffel syntax for accessing a data member and calling a function with no parameters is identical. So consider what we'd do in C++ to encapsulate a data member: we'd provide an accessor function. In Eiffel, the syntax to do would look like this: class GOOBER feature {ANY} get_value : INTEGER is do Result := value end feature {NONE} value : INTEGER end Now, imagine if, for convenience, you could name the accessor function the same name as the variable--the added word "get" doesn't really add anything to the equation here. What you'd end up with is a class which would behave *exactly* like this one: class GOOBER feature {ANY} value : INTEGER end More importantly, consider the purpose of encapsulation: the representation can be changed while the interface remains the same. That can happen here, too. The above class could change to use a DOUBLE for the representation of value: class GOOBER feature {ANY} value : INTEGER is do Result := double_value end feature {NONE} double_value : DOUBLE end This new class would act just like the old one as far as clients are concerned. So in conclusion, no, revealing the data members in this way does not break encapsulation. Note, however, that this relies on the Eiffel syntax whereby functions with no parameters are syntactically the same as data members. To answer your question, the client may be able to see the data members, but the client can't possibly *know* that that's what's going on. As far as any client knows, it's dealing with an accessor function. -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-29 0:00 ` Patrick Doyle @ 1997-08-29 0:00 ` Jon S Anthony [not found] ` <EFqDw0.3x7@ecf.toronto.edu> 0 siblings, 1 reply; 132+ messages in thread From: Jon S Anthony @ 1997-08-29 0:00 UTC (permalink / raw) In article <EFnK04.J43@ecf.toronto.edu> doylep@ecf.toronto.edu (Patrick Doyle) writes: > >Isn't that exactly the point? Why should a client be able to see the > >actual structure, aka implementation???? > > If you mean that Eiffel is letting the structure leak out by > providing access to data members, then that's not true. The No. That's not what I'm saying. I'm not commenting about the Eiffel approach at all (which in any event has nothing much to offer over the Ada approach here anyway - beyond certain personal preferences that is). > So in conclusion, no, revealing the data members in this > way does not break encapsulation. Note, however, that this No one claimed otherwise. > To answer your question, the client may be able to see > the data members, but the client can't possibly *know* This at least touches on my point and IMO, this is problematic. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <EFqDw0.3x7@ecf.toronto.edu>]
[parent not found: <JSA.97Aug30145354@alexandria.organon.com>]
* Re: Design By Contract [not found] ` <JSA.97Aug30145354@alexandria.organon.com> @ 1997-09-01 0:00 ` Patrick Doyle 0 siblings, 0 replies; 132+ messages in thread From: Patrick Doyle @ 1997-09-01 0:00 UTC (permalink / raw) In article <JSA.97Aug30145354@alexandria.organon.com>, Jon S Anthony <jsa@alexandria.organon.com> wrote: >In article <EFqDw0.3x7@ecf.toronto.edu> doylep@ecf.toronto.edu (Patrick Doyle) writes: > >> I'm afraid I don't know what your point is. But let me >> ask you this: Do you think providing accessor functions is >> OK? If so, what's the difference between accessors and the >> Eiffel approach? If not, why? > >Yes, (of course) providing accessor functions is OK. The differences >here are so trivial as to not be worth arguing about. Which is >probably the most important point here. Yes, but enlighten me. What are these trivial differences? I promise I won't laugh. :-) -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-28 0:00 ` Jon S Anthony 1997-08-29 0:00 ` Patrick Doyle @ 1997-08-29 0:00 ` Don Harrison 1997-08-29 0:00 ` Jon S Anthony 1 sibling, 1 reply; 132+ messages in thread From: Don Harrison @ 1997-08-29 0:00 UTC (permalink / raw) Jon S Anthony wrote: :In article <EFM140.Fy9@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: : :> - Strict enforcement of encapsulation while maximising visibility. Eiffel :> offers a look-but-don't-touch view of object attributes. In Ada83, :> an attribute and its type has to be declared in the visible interface in :> order for clients to see it's structure but then they can also update it :> directly. If you declare its type as private, clients can't update it :> directly but neither can they see its structure. : :Isn't that exactly the point? Why should a client be able to see the :actual structure, aka implementation???? No, the point is that there is no need to hide the structure of an attribute so long as it's read-only (look-but-don't-touch). These semantics allow you to query components of visible objects directly: a.SOME_TYPE ... if a.y > 0 then x := a.y end but prevent you from updating them directly (which would break encapsulation): a.y := x -- Illegal [You can update them *indirectly* by calling an operation in the object: a.set_y (x)] To get similar read-only semantics in Ada, you have to declare the attribute in the package body (hiding it) and return it via an exported function (which can't have the same name): the_a: SOME_TYPE ... function a return SOME_TYPE is begin return the_a; end; I prefer the Eiffel model because: - It's simple and direct. - It doesn't clutter the spec and body with functions. - It doesn't force you to invent multiple identifiers (one of which has a contrived name: "the_a" above). IMO, the other possibilities for attributes in Ada are unattractive because they are either too permissive (look-and-touch - attributes declared in the visible part of the spec) or too restrictive (don't-look-don't touch - private attributes). BTW, someone with a sense of humour may enjoy BM's discussion of Ada private types (OOSC-2, 33.4 - Hiding the Representation: The Private Story. P.1085-1087). [...] Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-29 0:00 ` Don Harrison @ 1997-08-29 0:00 ` Jon S Anthony [not found] ` <EFqE8L.4Eq@ecf.toronto.edu> 1997-09-02 0:00 ` Don Harrison 0 siblings, 2 replies; 132+ messages in thread From: Jon S Anthony @ 1997-08-29 0:00 UTC (permalink / raw) In article <EFnoJv.1vx@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > :Isn't that exactly the point? Why should a client be able to see the > :actual structure, aka implementation???? > > No, the point is that there is no need to hide the structure of an attribute > so long as it's read-only (look-but-don't-touch). These semantics allow you > to query components of visible objects directly: I'm not convinced that is sufficient. Knowing the structure can lead one into writing things that still depend on it (efficiency hacks come quickly to mind). > I prefer the Eiffel model because: > > - It's simple and direct. > - It doesn't clutter the spec and body with functions. > - It doesn't force you to invent multiple identifiers (one of which has > a contrived name: "the_a" above). Fine. Of course, all of these are simply _subjective_ characterizations. If that is what floats your boat - go for it. > IMO, the other possibilities for attributes in Ada are unattractive > because they are either too permissive (look-and-touch - attributes > declared in the visible part of the spec) or too restrictive > (don't-look-don't touch - private attributes). Again, this is simply personal perspective. It may mean a lot to you, but you should be aware that this subjective stuff ("unattractive" "too permissive" "too restrictive") is just opinion and preference and that others may well view _your_ preferences as "unattractive", "too permissive" and "too restrictive". There just is no consistent objective criteria here. And no amount of saying it's so will make it so. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <EFqE8L.4Eq@ecf.toronto.edu>]
[parent not found: <JSA.97Aug30145058@alexandria.organon.com>]
* Re: Design By Contract [not found] ` <JSA.97Aug30145058@alexandria.organon.com> @ 1997-09-01 0:00 ` Patrick Doyle 0 siblings, 0 replies; 132+ messages in thread From: Patrick Doyle @ 1997-09-01 0:00 UTC (permalink / raw) In article <JSA.97Aug30145058@alexandria.organon.com>, Jon S Anthony <jsa@alexandria.organon.com> wrote: > >Generally speaking, opinion (mine included) is irrelevant and just >leads to the complete waste of bandwidth these sorts of silly threads >suck up. Ok, if you want to turn this place into an online technical manual, fine. I think I'll keep reading others' opinions ("irrelevant" and "waste of bandwidth" as they may be) just in case I might actually learn something. -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-29 0:00 ` Jon S Anthony [not found] ` <EFqE8L.4Eq@ecf.toronto.edu> @ 1997-09-02 0:00 ` Don Harrison 1997-09-02 0:00 ` Jon S Anthony 1997-09-02 0:00 ` Joerg Rodemann 1 sibling, 2 replies; 132+ messages in thread From: Don Harrison @ 1997-09-02 0:00 UTC (permalink / raw) Jon S Anthony wrote: :In article <EFnoJv.1vx@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: : :> :Isn't that exactly the point? Why should a client be able to see the :> :actual structure, aka implementation???? :> :> No, the point is that there is no need to hide the structure of an attribute :> so long as it's read-only (look-but-don't-touch). These semantics allow you :> to query components of visible objects directly: : :I'm not convinced that is sufficient. Knowing the structure can lead :one into writing things that still depend on it (efficiency hacks come :quickly to mind). The thing is, though, that the designer of the supplier class *intends* the client to see the structure of attributes in just the same way as the author of an Ada interface *intends* clients to see the structure of a value returned by a function. Exporting happens on a need-to-know basis. If clients need attributes for any purpose (including efficiency tuning), then the supplier exports them. If they don't, then the supplier keeps them hidden. Note that in the extreme case of an attribute whose underlying class exports none of its attributes, you have the equivalent to an Ada private attribute. That is, the Ada package Some_Module is type My_type is tagged private; ... -- exported operations No_structure : My_type; private type My_type is tagged record ... -- hidden attributes end record; end; is roughly equivalent to the Eiffel class MY_CLASS feature ... -- exported operations feature {NONE} ... -- hidden attributes end class SOME_CLASS feature no_structure : MY_CLASS end So, if a supplier really needs to restrict what clients can see, for whatever reason, they're able to. However, the good thing about Eiffel is that it gives designers the flexibility of exposing as much or as little of an object's structure, in contrast with with Ada's you-see-it-all or you-see-nothing export policy. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-02 0:00 ` Don Harrison @ 1997-09-02 0:00 ` Jon S Anthony 1997-09-03 0:00 ` Don Harrison [not found] ` <JSA.97Sep3201329@alexandria.organon.com> 1997-09-02 0:00 ` Joerg Rodemann 1 sibling, 2 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-02 0:00 UTC (permalink / raw) In article <EFuuJK.GKu@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > So, if a supplier really needs to restrict what clients can see, for > whatever reason, they're able to. Agreed. Never claimed otherwise. > However, the good thing about Eiffel is that it gives designers the > flexibility of exposing as much or as little of an object's > structure, in contrast with with Ada's you-see-it-all or > you-see-nothing export policy. First, whether or not this is "good" depends on many things. Second, you can play the same game in Ada anyway: package P is type T is limited private; type S1 is tagged record ... end record; type S2 is ... end record; type Whatever is private; function Op1 (X : T) return S1; -- Expose S1 substructure function Op2 (X : T) return S2; -- Expose S2 substructure function Op3 (X : T) return Whatever; -- Don't expose this bit ... private ... end P; Also, even here, you it is possible to get at the remaining hidden structure if it is in the private portion with child packages. So, per usual, at the end of the day there really isn't enough overall differences on which to waste energy... /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-02 0:00 ` Jon S Anthony @ 1997-09-03 0:00 ` Don Harrison [not found] ` <JSA.97Sep3201329@alexandria.organon.com> 1 sibling, 0 replies; 132+ messages in thread From: Don Harrison @ 1997-09-03 0:00 UTC (permalink / raw) Jon S Anthony wrote: :In article <EFuuJK.GKu@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: [..] :> However, the good thing about Eiffel is that it gives designers the :> flexibility of exposing as much or as little of an object's :> structure, in contrast with with Ada's you-see-it-all or :> you-see-nothing export policy. I realised after writing this that you can export as much or as little as you like in Ada. In terms of individual attributes, you can do this by supplying a function if you want to export an attribute and by not supplying one if you want to hide one. :Second, you can play the same game in Ada anyway: Agree. :package P is : : type T is limited private; : : type S1 is tagged record : ... : end record; : : type S2 is ... end record; : : type Whatever is private; : : function Op1 (X : T) return S1; -- Expose S1 substructure : : function Op2 (X : T) return S2; -- Expose S2 substructure : : function Op3 (X : T) return Whatever; -- Don't expose this bit : :.... :private :.... :end P; Presumably, T here is composed of S1 and S2 among other things. I agree it gives similar functionality to Eiffel. :Also, even here, you it is possible to get at the remaining hidden :structure if it is in the private portion with child packages. Agree. BTW, I've just re-read the stuff on child packages (public and private) in the Ada95 Rationale. It's making more sense and I can see a couple of places in our recently completed simulation where private child packages would have been useful. They would have been handy for decomposing a couple of large abstractions into components while not exposing the internal interfaces to outsiders. I still prefer the Eiffel mechanisms for a couple reasons: a) Simpler b) Views may be directed to specific clients but it does seem to hold together pretty well. Also, it appears you can acheive comparable export granualarity in Ada and Eiffel. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <JSA.97Sep3201329@alexandria.organon.com>]
* Re: Design By Contract [not found] ` <JSA.97Sep3201329@alexandria.organon.com> @ 1997-09-04 0:00 ` Paul Johnson 1997-09-05 0:00 ` Jon S Anthony ` (2 more replies) [not found] ` <EFzLn7.481@ecf.toronto.edu> [not found] ` <EFz0pD.E6n@syd.csa.com.au> 2 siblings, 3 replies; 132+ messages in thread From: Paul Johnson @ 1997-09-04 0:00 UTC (permalink / raw) In article <JSA.97Sep3201329@alexandria.organon.com>, jsa@alexandria.organon.com says... >I believe that it is possible to get a reasonable level of this >awareness without such "steeping" - as long as you are very careful >about not confusing explicit _features_ with the _expressivity_ of the >languages. One may have a specific feature for capability X while the >other achieves X by a nice little combination or particular >utilization of some other features or constructs. And, understanding >this is really the key to rational and (more or less) objective >language comparisons. These are wise words. On the other hand I would hold that a language with direct support for something is better for that thing than a language which requires some idiom. For example Eiffel has direct support for multiple inheritance (MI). Ada requires you to play games with generic parameters in order to achieve the same effect. Here are the reasons I dislike idiomatic programming: 1: Its harder to read. The reader must "reverse engineer" the design of the system by looking at the idiom and recognising it. This generally requires that the reader be familiar with the idiom in question. I recall being totally flumoxed when I was learning assembler and came across my first "JMP" instruction at the end of a routine. Later of course, I learned the trick and would now understand such code. 2: Its harder to optimise. I suspect that MI in Ada provides another good example here. In Eiffel the various jump tables needed for MI can be optimised, for example by eliminating duplication. As far as I can see you can't do that in Ada because the compiler does not have the necessary information about what the programmer is doing. (BTW, I would be very interested in more information about that last point). Of course, this on its own would be an argument for a very large and complex language with specific support for just about everything. This would be a bad thing: simplicity in language design is a Good Thing. OTOH learning an idiom is not really any different to learning a language feature. So the skill in language design and evaluation is in determining which constructs are so common or require such complex idioms that they should be supported directly by the language. IMNHO, MI is such a feature. Paul. -- Paul Johnson | GEC-Marconi Ltd is not responsible for my opinions. | +44 1245 242244 +-----------+-----------------------------------------+ Work: <paul.johnson@gecm.com> | You are lost in a twisty maze of little Home: <Paul@treetop.demon.co.uk> | standards, all different. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-04 0:00 ` Paul Johnson @ 1997-09-05 0:00 ` Jon S Anthony 1997-09-08 0:00 ` Nick Leaton [not found] ` <5un58u$9ih$1@gonzo.sun3.iaf.nl> 2 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-05 0:00 UTC (permalink / raw) In article <5ulurp$aj8$1@miranda.gmrc.gecm.com> paul.johnson@gecm.com (Paul Johnson) writes: > These are wise words. On the other hand I would hold that a > language with direct support for something is better for that thing > than a language which requires some idiom. I hope you realize how relative this is to the problem space. Those who _really_ believe this have pursued the path of Application Specific Languages (ASLs), often with automatic generation (so called "meta generators"). Another option is CL, where you can basically build your own ASLs via macros (I suppose this counts as a kind of "meta idiom" as it is very typical technique in CL programming). > 2: Its harder to optimise. I suspect that MI in Ada provides another > good example here. In Eiffel the various jump tables needed for MI > can be optimised, for example by eliminating duplication. As far as > I can see you can't do that in Ada because the compiler does not have > the necessary information about what the programmer is doing. > > (BTW, I would be very interested in more information about that last point). I see absolutely nothing to justify this position. The instantiations happen at compile time and full information is available about what is happening. > Of course, this on its own would be an argument for a very large and > complex language with specific support for just about everything. This Not necessarily. Again, take a look at CL. > feature. So the skill in language design and evaluation is in determining > which constructs are so common or require such complex idioms that they > should be supported directly by the language. This sounds right to me. > IMNHO, MI is such a feature. And in mine, it's clearly _not_. If you are going to run down this sort of road, multiple dispatch (ala' CLOS) seems _clearly_ more fundamental than MI. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-04 0:00 ` Paul Johnson 1997-09-05 0:00 ` Jon S Anthony @ 1997-09-08 0:00 ` Nick Leaton 1997-09-08 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Paul Johnson [not found] ` <5un58u$9ih$1@gonzo.sun3.iaf.nl> 2 siblings, 2 replies; 132+ messages in thread From: Nick Leaton @ 1997-09-08 0:00 UTC (permalink / raw) > These are wise words. On the other hand I would hold that a language with > direct support for something is better for that thing than a language which > requires some idiom. There are some exceptions to this. I agree with you on MI for example, but if the idiom is particularly easy to express or occurs rarely, then there is no need to extend the language to cope. Having, somewhere in the language specification, a note on the idiom helps, because at least the solution is standard. > For example Eiffel has direct support for multiple inheritance (MI). Ada > requires you to play games with generic parameters in order to achieve > the same effect. > > Here are the reasons I dislike idiomatic programming: > > 1: Its harder to read. The reader must "reverse engineer" the design > of the system by looking at the idiom and recognising it. This > generally requires that the reader be familiar with the idiom in > question. I recall being totally flumoxed when I was learning > assembler and came across my first "JMP" instruction at the end of > a routine. Later of course, I learned the trick and would now understand > such code. Its like learning a spell which you must chant to protect yourself. .. Nick ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-08 0:00 ` Nick Leaton @ 1997-09-08 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Paul Johnson 1 sibling, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-08 0:00 UTC (permalink / raw) In article <VA.0000004d.486c7bde@nickle.compulink.co.uk>, nickle@compulink.co.uk wrote: >> For example Eiffel has direct support for multiple inheritance (MI). Ada >> requires you to play games with generic parameters in order to achieve >> the same effect. Thinking more about it, it really does make sense to implement mixin inheritance this way in Ada 95. The original poster probably wasn't "thinking in Ada." To declare an abstract data type in Ada, you do this: package P is type T is tagged private; ... end; Clients of type T with package P to get visibility to the type: with P; procedure Q is O : P.T; ... Now as far as clients of T are concerned, it doesn't matter whether P is a non-generic package, or the instantiation of a generic package. His manipulation of the type is the same. For example, we could have done this: generic ... package GP is type T is tagged ...; ... package P is new GP (...); My point is that from a client's point of view, it's exactly the same. He wants a type that has certain operations, so he withs a package containing that type. Now we have a certain abstraction into which we want to mix some other operations. What we're debating is how easy it is for the _mixer_ to do this. But who made this executive decision that MI is a better mechanism than genericity for combining abstractions? The key thing is that we're able to combine abstractions this way, _without_ an additional language feature. (This doesn't mean MI is bad, only that it's not needed.) Existing language mechanisms do _exactly_ what we want. The irony is that this isn't anying especially new: in Ada 83 we were _already_ combining abstractions this way (example: extending a list type with utility operations by importing the list type as a generic formal parameter). To say that MI is a "more elegant' mechanism of implementing mixin inheritance, or that Ada requires you to "play games" with generics (thus reducing the Ada mechanism to the status of a mere "idiom"), is a pretty impuissant argument. (Like my new word?) The generic technique is what Ada programmers have been doing all along (though not quite as simply as in Ada 95), so I'm not clear what you'd buy by using yet another mechanism whose superiority is only putative. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-08 0:00 ` Nick Leaton 1997-09-08 0:00 ` Matthew Heaney @ 1997-09-09 0:00 ` Paul Johnson 1 sibling, 0 replies; 132+ messages in thread From: Paul Johnson @ 1997-09-09 0:00 UTC (permalink / raw) In article <VA.0000004d.486c7bde@nickle.compulink.co.uk>, nickle@compulink.co.uk says... > >> These are wise words. On the other hand I would hold that a language with >> direct support for something is better for that thing than a language which >> requires some idiom. > >There are some exceptions to this. I agree with you on MI for example, but if the >idiom is particularly easy to express or occurs rarely, then there is no need >to extend the language to cope. Having, somewhere in the language specification, >a note on the idiom helps, because at least the solution is standard. Absolutely. I was careful in my original posting to say that direct support makes a language better *for that thing*. Of course an extra feature makes the language worse for other things. This is the balance that must be struck. Paul. -- Paul Johnson | GEC-Marconi Ltd is not responsible for my opinions. | +44 1245 242244 +-----------+-----------------------------------------+ Work: <paul.johnson@gecm.com> | You are lost in a twisty maze of little Home: <Paul@treetop.demon.co.uk> | standards, all different. ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <5un58u$9ih$1@gonzo.sun3.iaf.nl>]
* Re: Building blocks (Was: Design By Contract) [not found] ` <5un58u$9ih$1@gonzo.sun3.iaf.nl> @ 1997-09-06 0:00 ` Joachim Durchholz 1997-09-08 0:00 ` Paul Johnson 1 sibling, 0 replies; 132+ messages in thread From: Joachim Durchholz @ 1997-09-06 0:00 UTC (permalink / raw) Geert Bosch wrote: > I find that it is often better to combine simple building blocks > into the more complex one you need, than to use a more complex > feature that is not exactly what you need and may be overkill. When > combining ill-defined over-complex things like MI, C++ templates > and exceptions, you know for sure the result will be too complex > and not what you want. That myth again... MI by itself is neither complex nor ill-defined. Its C++ implementation is. If you want to see MI How It Should Be Done, look at one of the various Eiffel books. On the "building blocks" argument, I agree. Of course this will work only if language features are truly orthogonal. C++ is extremely bad in this respect, Ada is ways better (Eiffel really shines here, one has to actually look at the language to believe it). Regards, Joachim -- Please don't send unsolicited ads. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) [not found] ` <5un58u$9ih$1@gonzo.sun3.iaf.nl> 1997-09-06 0:00 ` Building blocks (Was: Design By Contract) Joachim Durchholz @ 1997-09-08 0:00 ` Paul Johnson 1997-09-08 0:00 ` Brian Rogoff 1 sibling, 1 reply; 132+ messages in thread From: Paul Johnson @ 1997-09-08 0:00 UTC (permalink / raw) In article <5un58u$9ih$1@gonzo.sun3.iaf.nl>, geert@gonzo.sun3.iaf.nl says... >Paul Johnson <paul.johnson@gecm.com> wrote: [On language features versus idiomatic programming] > For example Eiffel has direct support for multiple inheritance > (MI). Ada requires you to play games with generic parameters > in order to achieve the same effect.'' > >I find that it is often better to combine simple building blocks >into the more complex one you need, than to use a more complex >feature that is not exactly what you need and may be overkill. [Experiences based on Ada versus C++ omitted] Please don't judge a language feature (*any* feature) by its implementation in C++. The language is a bodge. Take a look at Eiffel instead. > When > combining ill-defined over-complex things like MI, C++ templates > and exceptions, you know for sure the result will be too complex > and not what you want. And if you do it in C++ I'd agree with you. However in Eiffel you will find that MI, templates and exceptions all fit together in a unified whole. In fact the Eiffel exception mechanism is superior to the Ada one because it is built on a theoretical model of software engineering. Paul. -- Paul Johnson | GEC-Marconi Ltd is not responsible for my opinions. | +44 1245 242244 +-----------+-----------------------------------------+ Work: <paul.johnson@gecm.com> | You are lost in a twisty maze of little Home: <Paul@treetop.demon.co.uk> | standards, all different. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-08 0:00 ` Paul Johnson @ 1997-09-08 0:00 ` Brian Rogoff 1997-09-09 0:00 ` Matthew Heaney ` (3 more replies) 0 siblings, 4 replies; 132+ messages in thread From: Brian Rogoff @ 1997-09-08 0:00 UTC (permalink / raw) On 8 Sep 1997, Paul Johnson wrote: > Please don't judge a language feature (*any* feature) by its implementation > in C++. The language is a bodge. If you read comp.lang.ada, you might learn that some people find certain aspects of C++ interesting, perhaps even worthy of being considered for inclusion in a future Ada :-). I suggest that you abandon your programming language religion when posting to multiple children of comp.lang. > Take a look at Eiffel instead. I have. And I used Sather for quite a while too. I find Ada superior to both, though I confess that I find Sather iterators extremely elegant and more importantly I wish garbage collection was the "default" for Ada. I think the module-type conflation is really confusion, and that OO is not the uber-paradigm which subsumes all others. > And if you do it in C++ I'd agree with you. However in Eiffel you will > find that MI, templates and exceptions all fit together in a unified > whole. In fact the Eiffel exception mechanism is superior to the Ada one > because it is built on a theoretical model of software engineering. I find it rather funny that in one post you say you don't use Ada, and can't understand the idioms for doing MI in Ada, but somehow you just "know" that it is a fact that the Eiffel exception mechanism is superior to Ada's. Ada exceptions can do everything Eiffel's can and more. (And before that "goto" vs "structured" analogy gets going, I find the extra power useful). Eiffel's inheritance is based on a theoretical model which later turned out to be unsafe. A (theoretical) fix was proposed, and never implemented. And now we have another theoretical fix. So much for Eiffel theoretical models! :-) -- Brian ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-08 0:00 ` Brian Rogoff @ 1997-09-09 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Brian Rogoff ` (3 more replies) 1997-09-09 0:00 ` W. Wesley Groleau x4923 ` (2 subsequent siblings) 3 siblings, 4 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-09 0:00 UTC (permalink / raw) In article <Pine.SGI.3.95.970908193446.11288B-100000@shellx.best.com>, Brian Rogoff <bpr@shellx.best.com> wrote: >>In fact the Eiffel exception mechanism is superior to the Ada one >> because it is built on a theoretical model of software engineering. Can any of the Eiffel guys explain this a bit more? I'm curious what is meant by a "theoretical model of software engineering." Can someone post some references to the theory behind the Eiffel exception mechanism? I've always been curious about the semantics of exception propagation, because it doesn't correspond to anything in pure math (or does it?). If I divide x by 0 on paper, I can strug my shoulders and say, "Oh well, division by 0 isn't defined," but on a computer, I have to do _something_. I just finished the Gordon book on denotational semantics, and even he just sort of says "return {error}"; maybe the Stoy book has something more. I read the Luckham paper, and he presented the idea that an assertion be associated with each exception raised by a subprogram, to describe the state when the exception is propagated. It would be cool if you could check at compile time that all exceptions were being handled by the client, and that only the exceptions advertised by a supplier get raised (and only in the specified state). Maybe that's the Eiffel model already. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 ` Matthew Heaney @ 1997-09-09 0:00 ` Brian Rogoff 1997-09-09 0:00 ` W. Wesley Groleau x4923 ` (2 subsequent siblings) 3 siblings, 0 replies; 132+ messages in thread From: Brian Rogoff @ 1997-09-09 0:00 UTC (permalink / raw) On Tue, 9 Sep 1997, Matthew Heaney wrote: > In article <Pine.SGI.3.95.970908193446.11288B-100000@shellx.best.com>, > Brian Rogoff <bpr@shellx.best.com> wrote: > > >>In fact the Eiffel exception mechanism is superior to the Ada one > >> because it is built on a theoretical model of software engineering. Watch your attributions, I didn't write that! > Can any of the Eiffel guys explain this a bit more? I'm curious what is > meant by a "theoretical model of software engineering." Can someone post > some references to the theory behind the Eiffel exception mechanism? The original poster probably meant that the Eiffel exception mechanism was designed to support Eiffel design by contract, so that when an exception is raised you retry or fail, restoring class invariants on leaving. I doubt he was talking about denotational semantics or theoretical models like that! You can read about DBC in Meyer's book or one of the many articles he's written. -- Brian ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Brian Rogoff @ 1997-09-09 0:00 ` W. Wesley Groleau x4923 1997-09-10 0:00 ` Robert A Duff 1997-09-10 0:00 ` Paul Johnson 1997-09-10 0:00 ` Robert Dewar 3 siblings, 1 reply; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-09 0:00 UTC (permalink / raw) > It would be cool if you could check at compile time that all exceptions > were being handled by the client, and that only the exceptions advertised > by a supplier get raised (and only in the specified state). Maybe that's > the Eiffel model already. Well, that's one good thing you can say about Java. Or is it (good)? -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 ` W. Wesley Groleau x4923 @ 1997-09-10 0:00 ` Robert A Duff 1997-09-12 0:00 ` Jon S Anthony 0 siblings, 1 reply; 132+ messages in thread From: Robert A Duff @ 1997-09-10 0:00 UTC (permalink / raw) In article <3415BA96.19B1@pseserv3.fw.hac.com>, W. Wesley Groleau x4923 <wwgrol@pseserv3.fw.hac.com> wrote: > >> It would be cool if you could check at compile time that all exceptions >> were being handled by the client, and that only the exceptions advertised >> by a supplier get raised (and only in the specified state). Maybe that's >> the Eiffel model already. > >Well, that's one good thing you can say about Java. Or is it (good)? No, it's not good. It leads to "crying wolf" -- that is, one must state that so-and-so might raise such-and-such exception, even when it's obvious it won't. Consider, for example, the stream classes in Java. A stream that represents a sequence of bytes read from an in-memory array has to falsely state that it might raise various I/O related exceptions, despite the fact that it has nothing whatsoever to do with I/O. The sentiment here is good, but it doesn't work given the paricular rules of Java, IMHO. Perhaps a different set of language rules could achieve the benefits without the "crying wolf" problems. - Bob ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-10 0:00 ` Robert A Duff @ 1997-09-12 0:00 ` Jon S Anthony 0 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-12 0:00 UTC (permalink / raw) In article <EG9ruK.BIq@world.std.com> bobduff@world.std.com (Robert A Duff) writes: > >> It would be cool if you could check at compile time that all exceptions > >> were being handled by the client, and that only the exceptions advertised > >> by a supplier get raised (and only in the specified state). Maybe that's > >> the Eiffel model already. > > > >Well, that's one good thing you can say about Java. Or is it (good)? > > No, it's not good. It leads to "crying wolf" -- that is, one must state > that so-and-so might raise such-and-such exception, even when it's > obvious it won't. Consider, for example, the stream classes in Java. A > stream that represents a sequence of bytes read from an in-memory array > has to falsely state that it might raise various I/O related exceptions, > despite the fact that it has nothing whatsoever to do with I/O. > > The sentiment here is good, but it doesn't work given the paricular > rules of Java, IMHO. Perhaps a different set of language rules could > achieve the benefits without the "crying wolf" problems. CORBA IDL has this same problem. Actually, it may have influenced the Java model as it certainly came B4 Java (I wonder if this bit of IDL can be traced back to Sun....) /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Brian Rogoff 1997-09-09 0:00 ` W. Wesley Groleau x4923 @ 1997-09-10 0:00 ` Paul Johnson 1997-09-10 0:00 ` Matthew Heaney 1997-09-10 0:00 ` Darren New 1997-09-10 0:00 ` Robert Dewar 3 siblings, 2 replies; 132+ messages in thread From: Paul Johnson @ 1997-09-10 0:00 UTC (permalink / raw) In article <mheaney-ya023680000909970121270001@news.ni.net>, mheaney@ni.net says... >In article <Pine.SGI.3.95.970908193446.11288B-100000@shellx.best.com>, >Brian Rogoff <bpr@shellx.best.com> wrote: >>>In fact the Eiffel exception mechanism is superior to the Ada one >>> because it is built on a theoretical model of software engineering. Brian Rogoff didn't write that, I did. >Can any of the Eiffel guys explain this a bit more? I'm curious what is >meant by a "theoretical model of software engineering." Can someone post >some references to the theory behind the Eiffel exception mechanism? I was referring to "design by contract", which underpins pretty much the whole of Eiffel. See OOSC-2 for the fullest explanation yet. E:TL also has quite a lot of stuff about it, and the theory was laid out in OOSC-1 in enough detail for a first pass. I think that there is also an outline on the ISE web site (www.eiffel.com). >I've always been curious about the semantics of exception propagation, >because it doesn't correspond to anything in pure math (or does it?). Under DbC, the server class offers a "contract" specified by the preconditions, postconditions and invariants. When a routine is called, the client must fulfil the preconditions (otherwise there is a bug in the client). Once these preconditions are fulfilled the server class must either fulfil the postconditions and invariants *or* raise an exception. In everyday programming this just means that it must fulfil its postconditions and invariants, but for instance an RPC mechanism might trigger an exception if it discovers that the network is down. Once an exception has been triggered the class has two options: 1. Tidy up any internal state and pass the exception back to the caller. 2. Try again, possibly using a different stratagy. Note that there is no third option. Also note that the following are forbidden: * Silent failure. If the server cannot fulfil its contract then it *must* raise an exception. * Exceptions as normal control structure. An exception indicates that something has gone wrong: things are not working as intended. It might be that the "something" is outside the software's control (e.g. network down) and the software has been written to handle this gracefully, but there is still something wrong. A dictionary lookup routine does not return an exception if it fails to find an entry. >It would be cool if you could check at compile time that all exceptions >were being handled by the client, and that only the exceptions advertised >by a supplier get raised (and only in the specified state). Maybe that's >the Eiffel model already. In Eiffel there is not much distinction between exceptions. You can examine an exception, but thats more so you can put something useful in the error log than for any control-flow reasons. As far as control flow is concerned, the key fact is that the routine has failed. Nothing else matters. In Ada exceptions seem to be treated as a sort of out-of-band enumerated type. Paul. -- Paul Johnson | GEC-Marconi Ltd is not responsible for my opinions. | +44 1245 242244 +-----------+-----------------------------------------+ Work: <paul.johnson@gecm.com> | You are lost in a twisty maze of little Home: <Paul@treetop.demon.co.uk> | standards, all different. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-10 0:00 ` Paul Johnson @ 1997-09-10 0:00 ` Matthew Heaney 1997-09-10 0:00 ` Darren New 1 sibling, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-10 0:00 UTC (permalink / raw) In article <5v5l26$h62$3@miranda.gmrc.gecm.com>, paul.johnson@gecm.com (Paul Johnson) wrote: >In Ada exceptions seem to be treated as a sort of out-of-band enumerated >type. It depends on the programmer - I have have seen many of the abuses you describe. However, I personally use Ada exceptions exactly as you recommend. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-10 0:00 ` Paul Johnson 1997-09-10 0:00 ` Matthew Heaney @ 1997-09-10 0:00 ` Darren New 1 sibling, 0 replies; 132+ messages in thread From: Darren New @ 1997-09-10 0:00 UTC (permalink / raw) >Note that there is no third option. Also note that the following are >forbidden: > >* Silent failure. If the server cannot fulfil its contract then it *must* > raise an exception. > >* Exceptions as normal control structure. An exception indicates that > something has gone wrong: things are not working as intended. Elaborating: Actually, I think the theoretical basis for the exceptions are that you cannot catch an exception and continue on. For example, if your calling code says x := him.blah(y) fooble(x) then if him.blah has a postcondition that Result>0, fooble can rely on getting an argument whose value is > 0. If him.blah fails to return the value that meets the postcondition, an exception is raised and passed to the caller. Hence, it is *impossible* to call fooble here with a negative value for x. There is no equivalent of try { x := him.blah(y) } catch (...) { /* do nothing */ } fooble(x) If every line of code does not fulfill its postconditions, it's impossible to execute the following line. And *that* I believe is what makes the exception mechanism helpful in reasoning about your code. Of course, it's also helpful that you do not have to catch errors in the wrong place. I very much dislike the Java mechanism when I try to implement an interface that does not throw IOException (for example) and I'm doing IO, so I have to figure out what the client is likely to want in terms of error handling, making reuse difficult. There are ways around it, but it's kludgey. -- Darren ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 ` Matthew Heaney ` (2 preceding siblings ...) 1997-09-10 0:00 ` Paul Johnson @ 1997-09-10 0:00 ` Robert Dewar 1997-09-12 0:00 ` Paul Johnson 1997-09-12 0:00 ` Jon S Anthony 3 siblings, 2 replies; 132+ messages in thread From: Robert Dewar @ 1997-09-10 0:00 UTC (permalink / raw) Brian Rogoff said <<>>In fact the Eiffel exception mechanism is superior to the Ada one >> because it is built on a theoretical model of software engineering.>> This is one of the more absurd statements in what is unfortunately becoming a rather tedious thread. First of all, the idea that being "built on *a* (i.e. any old) theoretical model of software engineering" is per se a good thing is a bit laughable. Second, of course the Ada exception mechanism is build on such a model also -- indeed it *is* a model itself! Rather thank make vague religeous statements like this which have zero meaning, say EXACTLY what technical point you are trying to make. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-10 0:00 ` Robert Dewar @ 1997-09-12 0:00 ` Paul Johnson 1997-09-14 0:00 ` Robert Dewar ` (2 more replies) 1997-09-12 0:00 ` Jon S Anthony 1 sibling, 3 replies; 132+ messages in thread From: Paul Johnson @ 1997-09-12 0:00 UTC (permalink / raw) In article <dewar.873938975@merv>, Robert Dewar <dewar@merv.cs.nyu.edu> writes >Brian Rogoff said > ><<>>In fact the Eiffel exception mechanism is superior to the Ada one >>> because it is built on a theoretical model of software engineering.>> As someone else pointed out, I said that, not Brian. >This is one of the more absurd statements in what is unfortunately becoming >a rather tedious thread. First of all, the idea that being "built on >*a* (i.e. any old) theoretical model of software engineering" is per se >a good thing is a bit laughable. In the original posting I was trying to be brief. I have since explained about design by contract and the Eiffel exception mechanism. >Second, of course the Ada exception mechanism is build on such a model >also -- indeed it *is* a model itself! If I understand you correctly, the Ada exception mechanism looks like it does because that was how the designers designed it. My original point was that the Eiffel mechanism looks like it does because the theory of software contracting required it to work that way. Actually I don't believe that the Ada designers just threw together its exception mechanism without thinking long and hard, and I don't think you really meant to imply it. However the lack of an underlying theory on its use and contribution to program correctness definitely shows up. Ada exceptions seem to have been designed as a way of unwinding the execution stack without letting the programmer break the language. The only reason for including it in the language was that programmers often want to do this. Paul. --------------------------------+--------------------------------- Paul Johnson | You are lost in a maze of twisty Email: Paul@treetop.demon.co.uk | little standards, all different. paul.johnson@gecm.com | ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-12 0:00 ` Paul Johnson @ 1997-09-14 0:00 ` Robert Dewar 1997-09-15 0:00 ` John G. Volan 1997-09-14 0:00 ` Robert Dewar 1997-09-14 0:00 ` Robert Dewar 2 siblings, 1 reply; 132+ messages in thread From: Robert Dewar @ 1997-09-14 0:00 UTC (permalink / raw) <<In the original posting I was trying to be brief. I have since explained about design by contract and the Eiffel exception mechanism.>> It is not at all the case that the abstract notion of design by contract dictates the design of the detailed syntax of the exception mechanism. Of course (as anyone familiar with the Ada design process are very aware), the Ada design of specifications is entirely focussed on the issue of what elements of the interface contract belong in the syntax of the language and what are best left to comments. The same statement can of course be made in Eiffel, so the theoretical bases, or more accurately, the fundamental design principles, are in fact very similar. The specific issue in Ada of whether it should be part of the syntax of the language to specify the exceptions that can be raised is of course one that was extensively discussed, and the quite deliberate decision was made that it is unhelpful to require these to be stated in the syntax. The reason is that there are too many exceptions (Storage_Error, or the various IO errors if any IO is done, or other application defined system wide exceptions) which would be named all over the place and create clutter. Note that Program_Error would also have to be named almost everwhere because of the Access Before Elaboration (ABE) considerations. SO there is no question of a presence or lack of theory here, rather it is a pragmatic issue of what should and should not go into the syntactical interface. Eiffel generally decides to put more into the syntax, but there is no real evidence to suggest that this is a good thing, it's mostly a subjective issue. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-14 0:00 ` Robert Dewar @ 1997-09-15 0:00 ` John G. Volan 0 siblings, 0 replies; 132+ messages in thread From: John G. Volan @ 1997-09-15 0:00 UTC (permalink / raw) Robert Dewar wrote: > > The specific issue in Ada of whether it should be part of the syntax of > the language to specify the exceptions that can be raised is of course > one that was extensively discussed, and the quite deliberate decision was > made that it is unhelpful to require these to be stated in the syntax. > > The reason is that there are too many exceptions (Storage_Error, or the > various IO errors if any IO is done, or other application defined system > wide exceptions) which would be named all over the place and create clutter. > Note that Program_Error would also have to be named almost everwhere because > of the Access Before Elaboration (ABE) considerations. There are a couple of strategies that could be applied to this problem: (1) Take certain common language-defined exceptions as givens (e.g., Storage_Error, Program_Error, Constraint_Error). That is to say, assume that they are implicitly part of the interface of every subprogram/method, and don't require the programmer to explicitly list them. (2) Make exceptions first-class objects, and take advantage of class hierarchies to simplify subprogram/method interfaces. For instance, IO exceptions might be organized into a hierarchy rooted at some abstract IO_Exception class. A method could declare that it can raise any IO_Exception, without having to explicitly list all the subclasses. As I understand it, this is essentially the strategy Java uses. I must admit that I like being able to treat exceptions as first-class objects organized in class hierarchies, and I miss that capability in Ada95. I wonder why this notion didn't catch on in the Ada95 design ... is it because first-class exceptions would have introduced a so-called "distributed overhead" into the language? -- Internet.Usenet.Put_Signature (Name => "John G. Volan", Employer => "Raytheon/TI Advanced C3I Systems, San Jose, CA", Work_Email => "jvolan@ti.com", Home_Email => "johnvolan@sprintmail.com", Slogan => "Ada95: World's *FIRST* International-Standard OOPL", Disclaimer => "My employer never defined these opinions, so using " & "them would be totally erroneous...or is that just " & "nondeterministic behavior now? :-) "); ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-12 0:00 ` Paul Johnson 1997-09-14 0:00 ` Robert Dewar @ 1997-09-14 0:00 ` Robert Dewar 1997-09-14 0:00 ` Robert Dewar 2 siblings, 0 replies; 132+ messages in thread From: Robert Dewar @ 1997-09-14 0:00 UTC (permalink / raw) <<If I understand you correctly, the Ada exception mechanism looks like it does because that was how the designers designed it. My original point was that the Eiffel mechanism looks like it does because the theory of software contracting required it to work that way.>> No, that is completely wrong, and if you want to find out why you are wrong, you should read the Ada Rationale. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-12 0:00 ` Paul Johnson 1997-09-14 0:00 ` Robert Dewar 1997-09-14 0:00 ` Robert Dewar @ 1997-09-14 0:00 ` Robert Dewar 2 siblings, 0 replies; 132+ messages in thread From: Robert Dewar @ 1997-09-14 0:00 UTC (permalink / raw) Paul said <<Actually I don't believe that the Ada designers just threw together its exception mechanism without thinking long and hard, and I don't think you really meant to imply it. However the lack of an underlying theory on its use and contribution to program correctness definitely shows up. Ada exceptions seem to have been designed as a way of unwinding the execution stack without letting the programmer break the language. The only reason for including it in the language was that programmers often want to do this. >> No need to believe or not believe anything here (actually you really use believe as a synonym for guess, but there is no need to guess). if you want to make statements about Ada Exception handling which you expect any one to pay attention to, do a little homework. And in particular, study the extensive material that is available to answer your question without guesses (your "seems to have been designed" is complete nonsense, as you will see if you do this homework!) ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-10 0:00 ` Robert Dewar 1997-09-12 0:00 ` Paul Johnson @ 1997-09-12 0:00 ` Jon S Anthony 1997-09-12 0:00 ` Robert Dewar 1 sibling, 1 reply; 132+ messages in thread From: Jon S Anthony @ 1997-09-12 0:00 UTC (permalink / raw) In article <dewar.873938975@merv> dewar@merv.cs.nyu.edu (Robert Dewar) writes: > Brian Rogoff said > > <<>>In fact the Eiffel exception mechanism is superior to the Ada one > >> because it is built on a theoretical model of software engineering.>> > > This is one of the more absurd statements in what is unfortunately becoming > a rather tedious thread. First of all, the idea that being "built on > *a* (i.e. any old) theoretical model of software engineering" is per se > a good thing is a bit laughable. Coming to Brian's defense here: He didn't say this, Paul Johnson said it. However, I fully agree with your characterization of the statement. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-12 0:00 ` Jon S Anthony @ 1997-09-12 0:00 ` Robert Dewar 1997-09-16 0:00 ` Brian Rogoff 0 siblings, 1 reply; 132+ messages in thread From: Robert Dewar @ 1997-09-12 0:00 UTC (permalink / raw) Jon said <<> Brian Rogoff said > > <<>>In fact the Eiffel exception mechanism is superior to the Ada one > >> because it is built on a theoretical model of software engineering.>> > > This is one of the more absurd statements in what is unfortunately becoming > a rather tedious thread. First of all, the idea that being "built on > *a* (i.e. any old) theoretical model of software engineering" is per se > a good thing is a bit laughable. Coming to Brian's defense here: He didn't say this, Paul Johnson said it. However, I fully agree with your characterization of the statement.>> Gosh, another horrible attribution error, that's twice in a week. Sorry about that Brian! ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-12 0:00 ` Robert Dewar @ 1997-09-16 0:00 ` Brian Rogoff 0 siblings, 0 replies; 132+ messages in thread From: Brian Rogoff @ 1997-09-16 0:00 UTC (permalink / raw) On 12 Sep 1997, Robert Dewar wrote: > <... I'm not including anything, it ends here :-) ...> > > Gosh, another horrible attribution error, that's twice in a week. Sorry > about that Brian! Ego te absolvo, Robert! :-) I agree that it would be nice if there were a more automatic way to determine who said what, when. -- Brian ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-08 0:00 ` Brian Rogoff 1997-09-09 0:00 ` Matthew Heaney @ 1997-09-09 0:00 ` W. Wesley Groleau x4923 1997-09-09 0:00 ` Veli-Pekka Nousiainen 1997-09-09 0:00 ` Veli-Pekka Nousiainen 3 siblings, 0 replies; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-09 0:00 UTC (permalink / raw) > > whole. In fact the Eiffel exception mechanism is superior to the > > Ada one because it is built on a theoretical model of software > > engineering. Theory is a good thing when it leads to progress. After it is confirmed by practical experience, it remains a good thing. As soon as it disagrees with practical experience, it becomes a Bad Thing. Ada's design had plenty of "theory" behind it. But it also had plenty of experienced people to shoot down any tendency to put excessive faith in theory. I can't personally say Eiffel's experience supports or disproves its theory. (Obviously, there are plenty of people already saying it supports it.) But I can say that "built on a theoretical model" is certainly no argument for superiority over Ada, or even over C. To change a word in an earlier quote: "A man with an experience is never at the mercy of a man with a theory." -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-08 0:00 ` Brian Rogoff 1997-09-09 0:00 ` Matthew Heaney 1997-09-09 0:00 ` W. Wesley Groleau x4923 @ 1997-09-09 0:00 ` Veli-Pekka Nousiainen 1997-09-09 0:00 ` Veli-Pekka Nousiainen 3 siblings, 0 replies; 132+ messages in thread From: Veli-Pekka Nousiainen @ 1997-09-09 0:00 UTC (permalink / raw) Unsafe? what is unsafe in Eiffel inheritance? And what is the fix? I have joined in much too late... VP Brian Rogoff <bpr@shellx.best.com> wrote in article <Pine.SGI.3.95.970908193446.11288B-100000@shellx.best.com>... <SNIP> > Eiffel's inheritance is based on a theoretical model which later turned out > to be unsafe. A (theoretical) fix was proposed, and never implemented. And > now we have another theoretical fix. So much for Eiffel theoretical > models! :-) > > -- Brian > ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-08 0:00 ` Brian Rogoff ` (2 preceding siblings ...) 1997-09-09 0:00 ` Veli-Pekka Nousiainen @ 1997-09-09 0:00 ` Veli-Pekka Nousiainen 1997-09-09 0:00 ` Jon S Anthony 3 siblings, 1 reply; 132+ messages in thread From: Veli-Pekka Nousiainen @ 1997-09-09 0:00 UTC (permalink / raw) Unsafe? what is unsafe in Eiffel inheritance? And what is the fix? I have joined in much too late... VP Brian Rogoff <bpr@shellx.best.com> wrote in article <Pine.SGI.3.95.970908193446.11288B-100000@shellx.best.com>... <SNIP> > Eiffel's inheritance is based on a theoretical model which later turned out > to be unsafe. A (theoretical) fix was proposed, and never implemented. And > now we have another theoretical fix. So much for Eiffel theoretical > models! :-) > > -- Brian > ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 ` Veli-Pekka Nousiainen @ 1997-09-09 0:00 ` Jon S Anthony 0 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-09 0:00 UTC (permalink / raw) In article <01bcbd1d$72196760$108142c1@Yeif-1.eiffel.fi> "Veli-Pekka Nousiainen" <vp.nousiainen@remove_this_eiffel.fi> writes: > Unsafe? what is unsafe in Eiffel inheritance? And what is the fix? > I have joined in much too late... > VP The polymorphic "CAT call" stuff, which rests ultimately on covariance which is one of the basic tenets underlying Eiffel's inheritance model. /Jon > Brian Rogoff <bpr@shellx.best.com> wrote in article > <Pine.SGI.3.95.970908193446.11288B-100000@shellx.best.com>... > <SNIP> > > Eiffel's inheritance is based on a theoretical model which later turned > out > > to be unsafe. A (theoretical) fix was proposed, and never implemented. > And > > now we have another theoretical fix. So much for Eiffel theoretical > > models! :-) > > > > -- Brian > > -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <EFzLn7.481@ecf.toronto.edu>]
* Re: Design By Contract [not found] ` <EFzLn7.481@ecf.toronto.edu> @ 1997-09-04 0:00 ` Jon S Anthony 0 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-04 0:00 UTC (permalink / raw) In article <EFzLn7.481@ecf.toronto.edu> doylep@ecf.toronto.edu (Patrick Doyle) writes: > >mechanism is clearly "simpler". b) can be done at a certain level via > >appropriate combination of public/private children, but it is not as > >encompassing as selective export. Then again, I've never had the > >experience where this extra selectivity would have been useful. > > I had an experience where selective export was really useful. I was > writing a circuit simulator, and I was using the builder pattern to > decouple the representation of the circuit from its construction. I > created features to add components and join them with wires. > > Then there was a CIRCUIT_SIMULATOR class which managed the event > queue for a circuit. It needed the ability to cause the circuit to > enact events, but I didn't want the builder to be able to enact > events because a) the circuit is not complete and b) the output > channel for the results of the simulation is not yet ready. > > Thus, I exported the circuit's enact_event feature to CIRCUIT_SIMULATOR > and solved that problem in a very straightforward way. Yes, but this is a good example of something that private children are intended for and which is straightforward to achieve with them. It is not a counter example to the "extra selectivity" capability of selective export. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <EFz0pD.E6n@syd.csa.com.au>]
* Re: Design By Contract [not found] ` <EFz0pD.E6n@syd.csa.com.au> @ 1997-09-05 0:00 ` W. Wesley Groleau x4923 1997-09-05 0:00 ` subjectivity W. Wesley Groleau x4923 [not found] ` <JSA.97Sep4172912@alexandria.organon.com> 2 siblings, 0 replies; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-05 0:00 UTC (permalink / raw) > :> I still prefer the Eiffel mechanisms for a couple reasons: > :> > :> a) Simpler > :> b) Views may be directed to specific clients > : > :Well, OK, but .... > :b) can be done at a certain level via > :appropriate combination of public/private children, but it is not as > :encompassing as selective export. I would say that public children allows selective import, and the "appropriate combination of public/private children" allows export to be selective, but only to the extent of choosing to export within the group or to everyone. > The sort of situations where it is handy is for tightly-knit > And in Ada a tightly-knit abstractions might be a collection of private children. -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity [not found] ` <EFz0pD.E6n@syd.csa.com.au> 1997-09-05 0:00 ` W. Wesley Groleau x4923 @ 1997-09-05 0:00 ` W. Wesley Groleau x4923 1997-09-05 0:00 ` subjectivity Matthew Heaney 1997-09-10 0:00 ` subjectivity Don Harrison [not found] ` <JSA.97Sep4172912@alexandria.organon.com> 2 siblings, 2 replies; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-05 0:00 UTC (permalink / raw) > :> a) Simpler > :> b) Views may be directed to specific clients > : > :Well, OK, but a) is subjective and viewed another way, the Ada > :mechanism is clearly "simpler". > > Looks like we have different ideas of what is simple. :( Which is why it is subjective. Unless we define "simple" as "easy for the speaker to use because he/she is accustomed to it." > I know you'll probably disagree, ..., but I believe simplicity is > innately, universally, and uniformly recognisable by everyone. > It's an aspect of human perception that occurs > automatically and intantaneously without conscious thought. > Because its a *perceived* quality, some believe it to be subjective. Since you and other(s), by your own admission, have "different ideas of what is simple," you should acknowledge that it is not "uniformly recognisable by everyone." Hence, it is subjective except when, in a particular forum, all participants agree on (in your words) "what measurable qualities engender the notion of simplicity and ... an 'objective' basis for measuring it." But perhaps this topic is ready to join Emmanuel Kant and Ayn Rand over on gnu.misc.discuss -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-05 0:00 ` subjectivity W. Wesley Groleau x4923 @ 1997-09-05 0:00 ` Matthew Heaney 1997-09-10 0:00 ` subjectivity Don Harrison 1997-09-10 0:00 ` subjectivity Don Harrison 1 sibling, 1 reply; 132+ messages in thread From: Matthew Heaney @ 1997-09-05 0:00 UTC (permalink / raw) In article <341026A7.37BE@pseserv3.fw.hac.com>, "W. Wesley Groleau x4923" <wwgrol@pseserv3.fw.hac.com> wrote: >Since you and other(s), by your own admission, have "different >ideas of what is simple," you should acknowledge that it is not >"uniformly recognisable by everyone." Hence, it is subjective >except when, in a particular forum, all participants agree on >(in your words) "what measurable qualities engender the notion >of simplicity and ... an 'objective' basis for measuring it." Here's a quote relevent to this thread: The idea that complexity is directly related to people's psychological being was recognized by Ashby. He argues that complexity depends on people's interests: "to the neurophysiologist the brain, as a feltwork of fibers and a soup of enzymes, is certainly complex; and equally the transmission of a detailed description of it would require much time. To a butcher the brain is simple, for he has to distinguish it from only about thirty other "meats."" From Dealing with Complexity, by Flood and Carson They also observe that "In general, we associate complexity with anything we find difficult to understand." That's why complexity can only be understood by considering both people _and_ things. There is no such thing as an "objective" measure of simplicity or complexity, because humans are involved, and every human has a different view of the system, depending on his interest. To the butcher, the brain isn't complex at all. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-05 0:00 ` subjectivity Matthew Heaney @ 1997-09-10 0:00 ` Don Harrison 1997-09-12 0:00 ` subjectivity Jon S Anthony 0 siblings, 1 reply; 132+ messages in thread From: Don Harrison @ 1997-09-10 0:00 UTC (permalink / raw) Matthew Heaney wrote: :Here's a quote relevent to this thread: : :The idea that complexity is directly related to people's psychological :being was recognized by Ashby. He argues that complexity depends on :people's interests: : :"to the neurophysiologist the brain, as a feltwork of fibers and a soup of :enzymes, is certainly complex; and equally the transmission of a detailed :description of it would require much time. To a butcher the brain is :simple, for he has to distinguish it from only about thirty other "meats."" : :From Dealing with Complexity, by Flood and Carson Nice quote. :They also observe that : :"In general, we associate complexity with anything we find difficult to :understand." Good definition. :That's why complexity can only be understood by considering both people :_and_ things. There is no such thing as an "objective" measure of :simplicity or complexity, because humans are involved, and every human has :a different view of the system, depending on his interest. To the butcher, :the brain isn't complex at all. The interest factor may be quite relevant here. My interest in minimality, uniqueness etc. certainly colours my own perception of simplicity. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-10 0:00 ` subjectivity Don Harrison @ 1997-09-12 0:00 ` Jon S Anthony 1997-09-16 0:00 ` subjectivity Don Harrison 0 siblings, 1 reply; 132+ messages in thread From: Jon S Anthony @ 1997-09-12 0:00 UTC (permalink / raw) In article <EGA65A.G1s@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > The interest factor may be quite relevant here. My interest in minimality, > uniqueness etc. certainly colours my own perception of simplicity. That's not all there is to it. What is being "minimized" and what is "unique" plays a central role as well. Minimizing "good" is not exactly what most people would pursue simply because it is "minimizing"... /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-12 0:00 ` subjectivity Jon S Anthony @ 1997-09-16 0:00 ` Don Harrison 1997-09-16 0:00 ` subjectivity Jon S Anthony 0 siblings, 1 reply; 132+ messages in thread From: Don Harrison @ 1997-09-16 0:00 UTC (permalink / raw) Jon S Anthony wrote: :In article <EGA65A.G1s@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: : :> The interest factor may be quite relevant here. My interest in minimality, :> uniqueness etc. certainly colours my own perception of simplicity. : :That's not all there is to it. What is being "minimized" and what is :"unique" plays a central role as well. Agree. Also, qualities may be beneficial in one *sense* and not another. For example, one could argue that minimal language mechanisms make a language easier to understand. But from another perspective, code implemented in such a language may be less easy to understand because more statements are required. This is one reason why reuse becomes so important when using minimalist languages. Further, minimalism has a performance overhead so increases the burden on compiler writers to optimise extensively. While there may be factors which derail it, this may be an argument in favour of Ada's "richness". Oops, I'd better take that back - I'm supposed to be a closed-minded language bigot! :) Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-16 0:00 ` subjectivity Don Harrison @ 1997-09-16 0:00 ` Jon S Anthony 0 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-16 0:00 UTC (permalink / raw) In article <EGL5CK.5IA@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > :That's not all there is to it. What is being "minimized" and what is > :"unique" plays a central role as well. > > Agree. Also, qualities may be beneficial in one *sense* and not another. > For example, one could argue that minimal language mechanisms make a > language easier to understand. > > But from another perspective, code implemented in such a language may be > less easy to understand because more statements are required. This is one > reason why reuse becomes so important when using minimalist languages. Yes, I completely agree. This differing perspectives looking into/at the same subject is the perceptive mode of investigation. The more such "legitimate" (which may be an issue itself) perspectives the clearer the issue will become. > Further, minimalism has a performance overhead so increases the > burden on compiler writers to optimise extensively. Right - or sometimes the other way 'round. > While there may be factors which derail it, this may be an argument > in favour of Ada's "richness". Oops, I'd better take that back - I'm > supposed to be a closed-minded language bigot! :) ;-), but yes, I think that from certain perspectives this is a plus and from others it may be a minus. Yes, exactly. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-05 0:00 ` subjectivity W. Wesley Groleau x4923 1997-09-05 0:00 ` subjectivity Matthew Heaney @ 1997-09-10 0:00 ` Don Harrison 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 1 sibling, 2 replies; 132+ messages in thread From: Don Harrison @ 1997-09-10 0:00 UTC (permalink / raw) W. Wesley Groleau wrote: : :> :> a) Simpler :> :> b) Views may be directed to specific clients :> : :> :Well, OK, but a) is subjective and viewed another way, the Ada :> :mechanism is clearly "simpler". :> :> Looks like we have different ideas of what is simple. :( : :Which is why it is subjective. No, it just means the concept of simplicity is probably being confused with something else - familiarity or ease-of-use, for example. : Unless we define "simple" as :"easy for the speaker to use because he/she is accustomed to it." You could but I think it would miss the mark. Ease-of-use can be due to a number of factors including familiarity and simplicity. If you're familiar with a language tool, it will tend to be easier to use but that doesn't necessarily mean it's simple. Also, if a tool is simple, it will tend to make it easy to use but may not be immediately so due to a lack of familiarity - the learning curve effect. If a tool is neither familiar nor simple (as APL was to me when I learnt it), it definitely won't be easy to use (and it wasn't). Simplicity tends to engender ease of use but is constrained by familiarity. Familiarity tends to engender ease of use but is constrained by simplicity. My experience of discovering Eiffel demonstrates these effects. It was immediately clear to me that Eiffel was simpler than Ada in spite of my familiarity with Ada. Just because it was simple didn't immediately make it easier to use, the reason being that it was unfamiliar. In particular, I wasn't familiar with the various idioms of OO in general, and Eiffel in particular, that would enable me to use it effectively. I'm still learning them. Clearly, if simplicity were the same as ease-of-use due to familiarity, I would have found Eiffel complex compared with Ada, but I didn't. :> I know you'll probably disagree, ..., but I believe simplicity is :> innately, universally, and uniformly recognisable by everyone. :> It's an aspect of human perception that occurs :> automatically and intantaneously without conscious thought. :> Because its a *perceived* quality, some believe it to be subjective. : :Since you and other(s), by your own admission, have "different :ideas of what is simple," you should acknowledge that it is not :"uniformly recognisable by everyone." I still think it is, if they take the trouble to identify personal bias. The signal is trying to get through to the brain, but other things such as familiarity and pre-conceived ideas are intent on derailing it. If we identified and filtered out those interfering factors, we would have the same perception of simplicity, IMO. Considering that is unlikely to happen, it's useful to circumvent that interference by examining the factors that give rise to the notion of simplicity. These factors, at least, are objective and provide a basis for comparison. :Hence, it is subjective :except when, in a particular forum, all participants agree on :(in your words) "what measurable qualities engender the notion :of simplicity and ... an 'objective' basis for measuring it." Sadly true. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-10 0:00 ` subjectivity Don Harrison @ 1997-09-10 0:00 ` W. Wesley Groleau x4923 1997-09-11 0:00 ` subjectivity Don Harrison 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 1 sibling, 1 reply; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-10 0:00 UTC (permalink / raw) Don Harrison wrote: > :> I know you'll probably disagree, ..., but I believe simplicity is > :> innately, universally, and uniformly recognisable by everyone. > :> It's an aspect of human perception that occurs > :> automatically and intantaneously without conscious thought. > :> Because its a *perceived* quality, some believe it to be subjective. AND > The interest factor may be quite relevant here. My interest in minimality, > uniqueness etc. certainly colours my own perception of simplicity. I rest my case. -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 @ 1997-09-11 0:00 ` Don Harrison 0 siblings, 0 replies; 132+ messages in thread From: Don Harrison @ 1997-09-11 0:00 UTC (permalink / raw) Matt Heaney wrote: :..He argues that complexity depends on people's interests.. and :.. we associate complexity with anything we find difficult to understand." I wrote: :The interest factor may be quite relevant here. My interest in minimality, :uniqueness etc. certainly colours my own perception of simplicity. Taking this further, we might recognise that these qualities (minimality, uniqueness etc. promote understanding, not just in individuals, but in people generally. This leaves us with: Minimality, uniqueness etc. promotes understandability which promotes the perception of simplicity. Caveat: I acknowledge that other people may be interested in other things - for example, redundancy, multiple ways of doing things, interdependencies, inconsistency etc. W. Wesley Groleau wrote: :I rest my case. Likewise. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: subjectivity 1997-09-10 0:00 ` subjectivity Don Harrison 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 @ 1997-09-10 0:00 ` W. Wesley Groleau x4923 1 sibling, 0 replies; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-10 0:00 UTC (permalink / raw) > If you're familiar with a language tool, it will tend to be easier to > use but that doesn't necessarily mean it's simple. Right. And if you think a feature of your favorite language is simple, you are either correct by your definition of simplicity or you are a closed-minded language bigot. No offense should be taken unless you _want_ to consider yourself the latter. :-) > My experience of discovering Eiffel demonstrates these effects. > It was immediately clear to me that Eiffel was simpler than Ada in > spite of my familiarity with Ada. It was immediately clear to you that Eiffel met your idea of simplicity. (Or it could be "I like Eiffel, Simplicity is good, therefore Eiffel is simple.) There are things in the Ada RM that I (and most Ada folks) do not consider simple, but which are the reason why certain things in Ada programs _are_ considered simple. So even when we agree on what is simple, it's still subjective. Since "definitions" are getting into the argument, shall we go to a meta-argument? Define "objective" and "subjective" When Frieda says, "X is simple" and Dana says, "No, X is complex." then I think they have not agreed on an objective measure of simplicity. Don thinks that one of them is correct, and the other is either lying, or is handicapped in the God-given ability to recognize simplicity. Supposing Don is right--it's still subjective which of them is correct. The only ways to end the argument between Dana and Frieda are for one of them to give in, or for both of them to agree on a measure of simplicity and apply it. For one of them to insist that the ability to recognize simplicity is innate will at best move the argument to the level of whether that is true. Then if they agree that is true, they can still argue which of them has that ability and which is handicapped. I think I have a God-given ability to recognize that this is not raising the argument to a higher level--it is lowering the argument several levels closer to idiocy. > The signal is trying to get through to the brain, but other things > such as familiarity and pre-conceived ideas are intent on derailing > it. If we identified and filtered out those interfering factors, we > would have the same perception of simplicity, IMO. Yes, if we identify the factors in my definition of simplicity that you disagree with, and I give them up, then we will have the same perception of simplicity. > Considering that is unlikely to happen, it's useful to circumvent that > interference by examining the factors that give rise to the notion of > simplicity. These factors, at least, are objective .... These factors are not objective until we name them, agree on what they mean, and agree on how to measure them. Now, IF we could come to such agreement (instead of continuing to argue about whether simplicity is objective), I suspect we would be forced to also agree that in certain areas, Eiffel is simpler, and in other areas, Ada is simpler. It would probably still be subjective how it plays out overall. So again, I suggest again: State why you believe a particular feature is an advantage or disadvantage. Provide, if available, measurements of results as evidence. Then if someone else disagrees (or doesn't think the thing you measured is important) either say to yourself he's an idiot and keep quiet, or continue discussing the _issue_. Whether you intended it or not, saying that something he disagrees about is obvious is the same as saying he is either blind or a liar. If he were either, what point is there in arguing? This subjectivity thing (including THIS post) is a waste of time. Let's cut it out. -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <JSA.97Sep4172912@alexandria.organon.com>]
[parent not found: <EG0oz8.F6M@syd.csa.com.au>]
* Re: Design By Contract [not found] ` <EG0oz8.F6M@syd.csa.com.au> @ 1997-09-05 0:00 ` Jon S Anthony 1997-09-05 0:00 ` Nick Leaton 1997-09-06 0:00 ` Patrick Doyle [not found] ` <EG0rp7.GtL@syd.csa.com.au> 1 sibling, 2 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-05 0:00 UTC (permalink / raw) In article <EG0oz8.F6M@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > Especially since you haven't shown how you think child packages can > give some of what selective export has to offer. It's a bit > difficult to give an example of what they *don't* offer if it's not > clear what they *do* offer. See Patrick's example. The point is, private children provide a level of "selective export" (exporting their interfaces only to their parent's body and certain parts of the private subtrees). IME, this has been quite sufficient. Eiffel's selective export is really much more like the granularity you get (and the attendant problems from) C++ friendship. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-05 0:00 ` Design By Contract Jon S Anthony @ 1997-09-05 0:00 ` Nick Leaton 1997-09-08 0:00 ` Jon S Anthony 1997-09-06 0:00 ` Patrick Doyle 1 sibling, 1 reply; 132+ messages in thread From: Nick Leaton @ 1997-09-05 0:00 UTC (permalink / raw) Jon S Anthony wrote: > > In article <EG0oz8.F6M@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > > > Especially since you haven't shown how you think child packages can > > give some of what selective export has to offer. It's a bit > > difficult to give an example of what they *don't* offer if it's not > > clear what they *do* offer. > > See Patrick's example. The point is, private children provide a level > of "selective export" (exporting their interfaces only to their > parent's body and certain parts of the private subtrees). IME, this > has been quite sufficient. > > Eiffel's selective export is really much more like the granularity you > get (and the attendant problems from) C++ friendship. Jon, What are the problems? I'm well aware with the issues that arise in C++, particularly with the all or nothing nature of C++ friendship. It is not as if you have to reveal your implementation. Selective revealing of interface I presume is OK, so what mechanism would you provide in its place? -- Nick Eiffel - Possibly the best language in the world - unless proven otherwise. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-05 0:00 ` Nick Leaton @ 1997-09-08 0:00 ` Jon S Anthony 1997-09-09 0:00 ` Nick Leaton 0 siblings, 1 reply; 132+ messages in thread From: Jon S Anthony @ 1997-09-08 0:00 UTC (permalink / raw) In article <341041A6.E45B6425@calfp.co.uk> Nick Leaton <nickle@calfp.co.uk> writes: > > Eiffel's selective export is really much more like the granularity you > > get (and the attendant problems from) C++ friendship. > > Jon, What are the problems? I'm well aware with the issues that > arise in C++, particularly with the all or nothing nature of C++ > friendship. It is not as if you have to reveal your > implementation. That's was not the issue I had in mind, it was more the "clairvoyance" problem of export for future clients. But really, Eiffel has a reasonable way around that which does not fall victim to the C++ problem. > Selective revealing of interface I presume is OK, so > what mechanism would you provide in its place? For something like Eiffel (where everything is defined via inheritance based classification), I think the solution provided is reasonable. /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-08 0:00 ` Jon S Anthony @ 1997-09-09 0:00 ` Nick Leaton 1997-09-10 0:00 ` Paul Johnson 0 siblings, 1 reply; 132+ messages in thread From: Nick Leaton @ 1997-09-09 0:00 UTC (permalink / raw) Jon S Anthony wrote: > > Selective revealing of interface I presume is OK, so > > what mechanism would you provide in its place? > > For something like Eiffel (where everything is defined via inheritance > based classification), I think the solution provided is reasonable. > I found things like Eiffel's use of inheritance for getting access to the facilities a little odd at first, but in practice it doesn't turn out to be a problem. Having good names for these classes help. One use is to get access to a set of constant objects in which case mostly we use _CONVENTION at the end of the class name. For functions such as sin and cos, then anthropromorphise (or the code equivalent ;-) ) the class, such as MATHEMATICIAN or STATISTICIAN. Some of are classes here end in _CALCULATOR fall into this category. It then makes it easy to identify or guess what the class is being used for. I would also put them at the end of the inheritance list if you are using MI. -- Nick Eiffel - Possibly the best language in the world - unless proven otherwise. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-09 0:00 ` Nick Leaton @ 1997-09-10 0:00 ` Paul Johnson 0 siblings, 0 replies; 132+ messages in thread From: Paul Johnson @ 1997-09-10 0:00 UTC (permalink / raw) In article <34150AE7.ABE4EDD6@calfp.co.uk>, nickle@calfp.co.uk says... >I found things like Eiffel's use of inheritance for getting access to >the facilities a little odd at first, but in practice it doesn't turn >out to be a problem. Having good names for these classes help. I agree. On the other hand, if you prefer not to pollute your namespace with all the stuff from the mixin class, you can do something like this: feature {NONE} math: expanded MATH; Now anywhere in your code you can write something like: a := math.sin (b) Its a bit like the use/with clauses in Ada. Paul. Paul -- Paul Johnson | GEC-Marconi Ltd is not responsible for my opinions. | +44 1245 242244 +-----------+-----------------------------------------+ Work: <paul.johnson@gecm.com> | You are lost in a twisty maze of little Home: <Paul@treetop.demon.co.uk> | standards, all different. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-05 0:00 ` Design By Contract Jon S Anthony 1997-09-05 0:00 ` Nick Leaton @ 1997-09-06 0:00 ` Patrick Doyle 1 sibling, 0 replies; 132+ messages in thread From: Patrick Doyle @ 1997-09-06 0:00 UTC (permalink / raw) In article <JSA.97Sep5130913@alexandria.organon.com>, Jon S Anthony <jsa@alexandria.organon.com> wrote: > >Eiffel's selective export is really much more like the granularity you >get (and the attendant problems from) C++ friendship. Perhaps it's "more like" but it's certainly very, very different. C++ has no granularity in its selective exports: you're either a friend or you're not. Either you're breaking encapsulation or you're not. In Eiffel, it's a matter of presenting different interfaces to different classes, and the mechanism is precise enough that encapsulation is maintained in all cases--just *different* encapsulations. -PD -- -- Patrick Doyle doylep@ecf.utoronto.ca ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <EG0rp7.GtL@syd.csa.com.au>]
* Re: Design By Contract [not found] ` <EG0rp7.GtL@syd.csa.com.au> @ 1997-09-05 0:00 ` Matthew Heaney 0 siblings, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-05 0:00 UTC (permalink / raw) In article <EG0rp7.GtL@syd.csa.com.au>, nospam@thanks.com.au wrote: >One obvious weakness of Ada child packages compared with Eiffel selective >export is a lack of symmetry. With selective export, two modules can >selectively export to each other. It's difficult to imagine how you could do >this elegantly with child packages, if at all. > >It may be necessary in Ada to co-encapsulate under such circumstances. In >that case, you lose the ability to control how each object updates the other's >state. This issue is frequently debated on comp.lang.ada, but I'll mention it again. The _reason_ modules and types are orthogonal is precisely so you can co-encapsulate types in the same package; this is why no "friend" instruction is needed in Ada. If two types need access to each other's state, then they are highly cohesive abstractions, and _should_ go in the same package. The argument that by using this idiom one "loses the ability to control how each object updates each other's state" isn't an issue in real programs. If such control were an issue, then perhaps the reason is that the abstractions are too large or complex. See John Volan's discussion about Ada's with'ing problem: <http://bluemarble.net/~jvolan/WithingProblem/FAQ.html> -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract [not found] ` <JSA.97Sep4172912@alexandria.organon.com> [not found] ` <EG0oz8.F6M@syd.csa.com.au> @ 1997-09-09 0:00 ` Robert A Duff 1997-09-09 0:00 ` Matthew Heaney 1 sibling, 1 reply; 132+ messages in thread From: Robert A Duff @ 1997-09-09 0:00 UTC (permalink / raw) >In article <EFz0pD.E6n@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: > >> I know you'll probably disagree, (and this is getting into Matt >> Heaney territory), but I believe simplicity is innately, >> universally, and uniformly recognisable by everyone. ... Then how come not everyone in this thread seems to agree on what's simpler than what? - Bob ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-09 0:00 ` Robert A Duff @ 1997-09-09 0:00 ` Matthew Heaney 0 siblings, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-09 0:00 UTC (permalink / raw) In article <EG9Eo4.318@world.std.com>, bobduff@world.std.com (Robert A Duff) wrote: >>In article <EFz0pD.E6n@syd.csa.com.au> nospam@thanks.com.au (Don Harrison) writes: >> >>> I know you'll probably disagree, (and this is getting into Matt >>> Heaney territory), but I believe simplicity is innately, >>> universally, and uniformly recognisable by everyone. ... > >Then how come not everyone in this thread seems to agree on what's >simpler than what? Exactly. Read my previous post about the difference between a neurophysiologist and a butcher: to the butcher, the brain is quite simple indeed! And that's precisely the issue. Complexity depends on things _and_ people, because everyone's interest is different. Read Dealing with Complexity, by Carson and Flood, for a good introduction to the concepts. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-02 0:00 ` Don Harrison 1997-09-02 0:00 ` Jon S Anthony @ 1997-09-02 0:00 ` Joerg Rodemann 1997-09-02 0:00 ` Jon S Anthony 1 sibling, 1 reply; 132+ messages in thread From: Joerg Rodemann @ 1997-09-02 0:00 UTC (permalink / raw) Don Harrison (nospam@thanks.com.au) wrote: > The thing is, though, that the designer of the supplier class *intends* the > client to see the structure of attributes in just the same way as the author > of an Ada interface *intends* clients to see the structure of a value > returned > by a function. > Exporting happens on a need-to-know basis. If clients need attributes for > any purpose (including efficiency tuning), then the supplier exports them. > If they don't, then the supplier keeps them hidden. Note that in the > extreme > case of an attribute whose underlying class exports none of its attributes, > you have the equivalent to an Ada private attribute. That is, the Ada I wonder what this is all about? In Ada as well as in Eiffel you have to decide if you grant a client read, read/write or none access to any member variables of an object. Certainly the syntax of the following implementations differ --- and in this case tend to need a few more characters in the Ada version. Although there is a slight difference: in Ada you arrange one or more 'class' definitions in a package whereas the feature mechanism of Eiffel reminds me a little bit of the friend declarations in C++. (Sorry if I got this wrong, I just had a short glance at Eiffel yet.) But at least I do not recognize any fundamental difference between the explicit declaration of a function and the possibility to use a member variable as if it was a function. (As far as I remember there is some construct in Ada where a similar interpretation is used. Perhaps someone else has a better memory than me...must have been digging up too many memory problems in C++ lately ;-> ) I occurs to me that the differences this thread is all about start from a slight difference in writing. (You use more words to say this, so mine is better. As in while ( cond ) { while cond loop ... vs. ... } end loop; Well, of course just my opinion Yours Joerg -- rodemann@mathematik.uni-ulm.de | Dipl.-Phys. Joerg S. Rodemann Phone: ++49-(0)711-5090670 | Flurstrasse 21, D-70372 Stuttgart, Germany -------------------------------+--------------------------------------------- rodemann@rus.uni-stuttgart.de | University of Stuttgart, Computing Center Phone: ++49-(0)711-685-5815 | Visualization Department, Office: 0.304 Fax: ++49-(0)711-678-7626 | Allmandring 30a, D-70550 Stuttgart, Germany ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-09-02 0:00 ` Joerg Rodemann @ 1997-09-02 0:00 ` Jon S Anthony 0 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-02 0:00 UTC (permalink / raw) In article <340bb873.0@news.uni-ulm.de> rodemann@mathematik.uni-ulm.de (Joerg Rodemann) writes: > I wonder what this is all about? In Ada as well as in Eiffel you have to > decide if you grant a client read, read/write or none access to any member > variables of an object. Exactly. > Certainly the syntax of the following implementations differ --- and > in this case tend to need a few more characters in the Ada > version. Although there is a slight difference: in Ada you arrange > one or more 'class' definitions in a package whereas the feature > mechanism of Eiffel reminds me a little bit of the friend > declarations in C++. (Sorry if I got this wrong, I just had a short > glance at Eiffel yet.) > Yes, this pretty much sounds on target as well. > But at least I do not recognize any fundamental difference between the > explicit declaration of a function and the possibility to use a member > variable as if it was a function. Agreed here too. > this thread is all about start from a slight difference in writing. (You > use more words to say this, so mine is better. As in You've just hit the nail on the head, IOW, "much ado about nothing"... /Jon -- Jon Anthony OMI, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract [not found] ` <EFM140.Fy9@syd.csa.com.au> 1997-08-28 0:00 ` Jon S Anthony @ 1997-08-28 0:00 ` Robert Dewar 1997-08-29 0:00 ` Don Harrison 1 sibling, 1 reply; 132+ messages in thread From: Robert Dewar @ 1997-08-28 0:00 UTC (permalink / raw) Don says << - Simplicity which enables developers to focus on designing rather than trying to remember language rules. A simplistic macroscopic comparison of Eiffel and Ada based on the number of validity rules suggests that Eiffel is about 50 times simpler than Ada.>> Simplicity is a very slippery term, what do you mean: Simplicity of the description Simplicity of format definition Simplicity of programming applications Simplicity of implementation These are nowhere *near* the same thing. For example, let's compare the floating-point rules in C and Ada. Gosh, C is FAR simpler, look at all those rules in annex G in Ada, not to mention the basic stuff in chapter 3. None of that nonsense in C, C is much simpler. But suppose the task is: write portable numerical codes. Oops, now we are in big trouble in C, and the task is far *more* complex, because now we have no guarantees from the language, and either the task is impossible, or involves all kinds of complex external configuration control. It is helpful whenever you use the word simple or complex to say exactly what domain you are talking about. I see all the time people playing the game where they argue simplicitly in one of these domains, implicitly appealing to people's agreement that simplicity in another domain is crucial. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design By Contract 1997-08-28 0:00 ` Robert Dewar @ 1997-08-29 0:00 ` Don Harrison 0 siblings, 0 replies; 132+ messages in thread From: Don Harrison @ 1997-08-29 0:00 UTC (permalink / raw) Robert Dewar wrote: :Don says : :<< - Simplicity which enables developers to focus on designing rather than : trying to remember language rules. A simplistic, macroscopic comparison : of Eiffel and Ada based on the number of validity rules suggests that : Eiffel is about 50 times simpler than Ada.>> : : :Simplicity is a very slippery term, what do you mean: : :Simplicity of the description :Simplicity of format definition :Simplicity of programming applications :Simplicity of implementation It's perhaps more convenient to express this in terms of the opposite quality: complexity. What I mean specifically is the complexity of relationships between language features (including libraries) in terms of its impact on developing applications. :These are nowhere *near* the same thing. For example, let's compare the :floating-point rules in C and Ada. Gosh, C is FAR simpler, look at all :those rules in annex G in Ada, not to mention the basic stuff in chapter :3. None of that nonsense in C, C is much simpler. : :But suppose the task is: write portable numerical codes. Oops, now we are :in big trouble in C, and the task is far *more* complex, because now we :have no guarantees from the language, and either the task is impossible, :or involves all kinds of complex external configuration control. Yes, I agree there are problems in attempting to compare languages when one provides a facility and another doesn't. In such cases, it's necessary to add appropriate hypothetical mechanisms to the one that lacks them to compare fairly. In the case of Eiifel, you would need to add certain standard and optional class libraries, for example, to compare it with Ada. Even though my formula for relative complexity is macroscopic, I think it has a sufficiently objective basis to be of some interest. It does require some more accurate data than I currently have at my disposal. In particular, I would like to know: How many distinct numbered validity requirements are there in: - The core language part of the Ada RM - Each Annexe of the Ada RM What I mean is how many of these: RM 10.1.2(4), for example. (Examples should be omitted). If you, or anyone is willing to supply this information, I'll post the formula and a discussion of it. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <349224633wnr@eiffel.demon.co.uk>]
* Re: Design by Contract [not found] ` <349224633wnr@eiffel.demon.co.uk> @ 1997-08-27 0:00 ` Robert Dewar 1997-08-29 0:00 ` Don Harrison 1 sibling, 0 replies; 132+ messages in thread From: Robert Dewar @ 1997-08-27 0:00 UTC (permalink / raw) Roger says <<Ada would benefit (for some applications) from Eiffel's garbage collection. Apart from that, Ada has quite satisfactory ways of doing what Eiffel has to offer. Although I prefer Eiffel's simple class-centric model and its more disciplined exception model, Ada is certainly very usable without these.>> As has been often pointed out, this is not a language issue, there is nothing in the design of Ada that prohibits garbage collection, and indeed some though has been given in the design to making sure nothing stands in its way (unlike the case with C or, to a somewhat lesser extent withy C++). Indeed there is at least one Ada implementation (the Intermetrics Ada-to_Java compiler) that provides garbage collection, and soon there will be at least one more. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Design by Contract [not found] ` <349224633wnr@eiffel.demon.co.uk> 1997-08-27 0:00 ` Design by Contract Robert Dewar @ 1997-08-29 0:00 ` Don Harrison 1 sibling, 0 replies; 132+ messages in thread From: Don Harrison @ 1997-08-29 0:00 UTC (permalink / raw) Roger Browne wrote: :"W. Wesley Groleau x4923" <wwgrol@pseserv3.fw.hac.com> writes: : :> Suppose Ada added Eiffel assertions and Eiffel added separate :> compilation of specs. Or even some sort of automated control that :> prevented changing contract without special privilege. : :No change is required to Eiffel to enable project managers to keep a hold of :the specs whilst letting programmers loose on the implementation. : :Simply code the spec as abstract classes in separate (locked) files and let :the programmers write the concrete implementation in child classes. I tend to think deferred classes are not the proper analogue of Ada package specifications. Ada package specs, unlike Eiffel deferred classes exist for every module, so a better analogue for this module concept may be the class short form. Deferred classes (specifically, the type aspects of them) are more analogous to Ada abstact types, IMO. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <3406BEF7.2FC3@flash.net>]
[parent not found: <3406E0F7.6FF7ED99@calfp.co.uk>]
* Re: Critique of Ariane 5 paper (finally!) [not found] ` <3406E0F7.6FF7ED99@calfp.co.uk> @ 1997-09-02 0:00 ` Ken Garlington 0 siblings, 0 replies; 132+ messages in thread From: Ken Garlington @ 1997-09-02 0:00 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 17192 bytes --] Nick Leaton wrote: > > Ken Garlington wrote: > > > > Nick Leaton wrote: > > > > > > 1) Additional effort. > > > There is plenty of evidence that the cost of finding and fixing a bug > > > early in the development process is much cheaper that fixing it later. > > > Now *IF* DBC as a methodology produces earlier detection of faults, then > > > this 'additional effort' is justified, as it is effort early in the > > > development process. > > > > No, re-read the quote: It can't just produce earlier detection of > > faults; > > it must be _better_ at detecting them early than _all_ other available > > alternatives. Otherwise, you're not using your resources effectively. > > Wrong. You have to cost the resource. Which is exactly what I am saying! You have to assign a cost to DBC, and compare it to the alternatives. > I am asserting > > 1. It catches many bugs early. Evidence is personal experience and > others > have posted the same. This statement provides no guidance as to assigning cost. It catches bugs "early" - but not earlier than analysis of the UML (a la Jezequel) for example. Thus, if this were the only criteria, DBC would not be the best alternative. > > 2. It is not expensive adding in assertions. There is a huge overlap in > writting an assertion and producing a correct specification so it is > not > wasted work. "Expensive" is a relative term, and this statement provides no guidance as to the _comparison_ (vs. what baseline?) you are making. If you are saying, "it is less expensive than writing a poor specification," then we agree. However, DBC is not the only alternative to writing a good specification, nor is writing a good specification the only factor in producing quality software. > You now have to say what ALL the other resources are and what the costs > are > in using them to justify your statement. My statement is "you now have to say what ALL the other resources are and what the costs are in using the to justify the statement: DBC is the best alternative." I'm glad we agree on this point. Remember, fellow debators: The affirmative (DBC) has the burden of proof, not the negative! See: the principles of (a) status quo and (b) inherency. > > > Furthermore, if it detects 20% of the total system faults early, but > > as a result there isn't sufficient resources to use other techniques > > to find the resulting 80% that are left, then although you fixed the > > 20% more cheaply than some other alternative, you have still delivered > > a system with 80% of the faults remaining. So, coverage of the faults > > by quantity is an issue as well as speed. > > But you assume that the other resources will find the faults within your > resource budget. What if you haven't the resources, which is your > argument against > DBC? Can you fit a quart in a pint pot? No, no, Nanette! I make no such assumption. YOU have the burden of proof here. I don't have to _assume_ anything! You're repeating my argument exactly. You _can't fit a quart in a pint pot. Therefore, DBC must not only be effective; it must the the _most_ effective of the alternatives. > You have assumed that using DBC uses up resources at such a rate that it > stops you producing product. Implementing DBC does not take up huge > resources at the coding stage. "Huge..." what a (relative) concept! > At the design stage you should be > specifying what you want to have happen at the level required to > implement DBC, so there is no additional resources going to waste here. Now you have made a statement you will have to defend vigourously. This statement says that DBC takes _zero_ resources more than the alternatives. > > DBC is cost effective Prove it! > as a method of producing quality code, and does > not take major resources Post some numbers! > to achieve. Having a compiler help you makes a > big difference, which is where the Eiffel part comes into play. "big"... compared to what! > > > Finally, even if DBC discovers 95% of the faults, but the remaining 5% > > are the most serious, you still have a problem. So, the ability to > > detect the most serious faults, as well as the quantity and speed, must > > be evaluated vs. _all_ alternatives. > > All programmers reading this, if offered a method that found 95% of bugs > the first time they executed a particular path in their code, would > welcome it. It leaves them with more resources to work on the hard 5% Not if the effort to get the 95% fails to get the 5%. By the way, _safety-critical_ programmers do not agree with this statement. I will gladly release software with several minor problems in order to make sure I have found and corrected the critical problems. > > > That's the common fallacy of the Eiffel advocate argument: "It's better > > than what I was doing, so go use it." However, was what you were doing > > before the best approach (excluding Eiffel)? > > I was not necessarily using the ideal approach before, but I haven't > made this statement. Actually, you have. You just don't realize it. > I have found in practice, that DBC as a method > works. You have to propose other ways of achieving what DBC achieves, > with less effort. Again, it's not my argument to make. You have the burden of proof. 2+2=4, therefore God exists! Dispute it! > > > > 2) Time spent else where. > > > Is this the case? Some of it may be, but I believe if you cannot be > > > rigourous about what your software is trying to do, by writing > > > assertions, then you are unlikely to produce a quality system. > > > > Bad argument. You haven't proven that "writing software rigorously" > > is _best_ done by "writing assertions." For that matter, you haven't > > shown that the "writing" (coding?) phase is the most critical with > > respect to producing a quality system. Consider, for example, that > > there are approaches that can generate software with no manual coding... > > Eh? (the last sentence) Welcome to the world of autocoding! See http://www.ise.com for one of many examples. > > > > The > > > effect of writing assertions overlaps with the design process. It is not > > > wasted time, it just comes under a different heading. If your design > > > process listed the assertions in the specification, would implementing > > > them be a waste of effort? > > > > Yes, quite possibly, implementing assertions in the code may be both > > ineffective and counter-productive, compared to other approaches, > > depending > > upon circumstances. > > What other approaches? What evidence do you have? (PS I have read your > critique) What other approaches are there to quality software? Let us list the ways: Formal reasoning, use cases, patterns, cleanroom, N-version programming, PSP, power CASE, FMET, autocoding, reuse... (everbody sing along!) Without quantitative measures, you're preaching a religion, not evaluating a technique. > > > 3) Simple software. > > > You bet. The simpler the better. Occams Razor rules. Now here there is a > > > split between DBC a la Eiffel and DBC, say in C++. In Eiffel it is > > > simple. > > > > "Simple software" is not synonymous with "easiler to write code." The > > question > > is: is software with assertions less complex than software without > > assertions. > > Based on measures of merit such as lines of code, paths, etc. the answer > > is > > "no". > > Given a complex solution and a simple solution to the same problem, the > simple solution is the one with merit. Period. > > If you don't assert your software, then you have to write test code to > test the same assertions (specification) in order to satisfy yourself it > is correct. Test oracles, debugger scripts, reliability models, structural testing, etc. There is a whole world of means to "satisfy yourself it is correct" beyond writing test code (who does this sort of trash anymore, anyway? We haven't done it in at least 5 years!). > DBC on your measures of merit stated above, when you take the whole > system into account will be better. Only if you're comparing it to an obsolete alternative (as you did). > > > > In C++ it is hard, particularly with inheritance of assertions. > > > > Again, this is the fallacy of the argument. Why are you comparing Eiffel > > to > > C++? (The second fallacy: Why are you comparing languages when > > discussing > > DBC as a methodology?) > > > > > One common theme from Eiffel practitioners is their support for DBC. > > > Why? They are simple to write. > > > > As a motivation, consider this: > > > > Here is a simple assertion: > > > > "The sun is hot." > > > > Now, put this in your code as a comment. Is the code simpler as a > > result? > > Put it in 1,000 times (simple to do with a text editor, right)? Is > > the code simpler as a result? > > > > > Assertions affect timing in safety critical systems. > > > > > > Firstly it depends on the implementation. It is easy to envisage a > > > system where the assertions are redundantly executed. But you would only > > > want to do that if you were running with faulty software ?!*^�% > > > > > > I also find it worrying that systems are being used for safety critical > > > apps where there is the possibility of a race or deadlock to occur. > > > > Then you would agree that it is critical to test systems to ensure that > > such possibilities are not present, correct? And so, doing things which > > mask the presence of such errors during testing are bad, right? So, > > you agree with my argument! > > > > If we are to assume the system is implemented correctly, why bother with > > assertions as a means to validate system correctness! > > Because you want to be sure it is implemented correctly! But you already assumed the system is implemented correctly! Why are you now unsure! > > > I am always amazed when people don't grasp this. It's not that the > > system is designed intentionally to permit race or deadlock; the concern > > is making sure that you didn't _inadvertantly_ do this! It's like > > saying: > > > > "I also find it worrying that systems are being used for safety critical > > apps where there is the possibility of faults to occur." as an argument > > for not testing at all! > > > > > Compilation problems. > > > These can occur in any system as you are aware. From discussions with > > > some of the people involved in writting Eiffel compilers, the enabling, > > > disabling of assertions has a very trivial implementation, which is very > > > unlikely to go wrong. > > > > Define "unlikely". As I note in the paper, no evidence has been provided > > regarding this issue. My argument is that, the more complexity added to > > the software, the more likely the introduction of a fault due to a > > compiler > > bug. > > Do some thinking about how you would implement DBC if you were a > compiler writer. Consider how to enable, disable the assertions. Is this > a 'hard problem' to solve? Yes, based on real experience with real compilers. (I know that real experience doesn't compete with theory, but I find it comforting nonetheless :) > > > Would you be willing to use a safety-critical system if the engineer > > said, > > "Well, we didn't actually test the code we fielded, but we tested code > > that was pretty much the same."? > > No. I would do the testing. I'm not stupid. So much for zero cost DBC! You now get to do the testing twice. Compare to just _one_ alternative: coding the assertions in a debugger script using real-time non-intrusive monitoring. Since the assertions are outside the code, you can (1) test just once (since the assertions do not affect the code) and (2) have the assertions reference objects not in the code (e.g. values in the external environment not directly available to the code under test). These assertions can be generated from a test oracle hooked up to a UML (or other notation) model of the system, if you like. They can be incorporated into a "short form" of the spec for review. So, compared to DBC, they do the same thing (assuming you were not going to have the assertions execute during production) and cost less. We do this today, so we know it works. Since we agree on comparitive cost as the criteria, you now have to show why this alternative costs more. (The negative has introduced an alternative plan, with no inherency! Incredible!) > > > It has also be extensively tested in the field by > > > end users. > > > > Insufficient. How many years had the Ariane IV IRS been flown before it > > was installed in the Ariane V? > > Agreed. But give yourself the choice. > > a) Tested by software engineers. > > b) Tested by software engineers and lots of users. Invalid. Show that the Eiffel compiler meets the first clause of (a), and to what extent. The true choice is: a) Tested by software engineers to a known standard. b) Used in various domains (not your own), and tested to some unknown standard. I'll be taking "a", please! > > > > Do you trust your compiler? If not, you shouldn't be writing safety > > > critical software with it. Period. > > > > Irrelevant. Much like saying, "I trust my development team, so I won't > > test their products." Blindly "trusting" any part of the development > > process is extremely dangerous. > > See you argument above, I'll quote it again > > * If we are to assume the system is implemented correctly, why bother > with > * assertions as a means to validate system correctness! > > This is why assertions are good. You don't blindly trust. Interesting that you quote your own argument to reinforce your own argument! You are the one who assumed the system was implemented correctly, remember? I was the one who pointed out this was a bad idea. Glad we could agree that we should not assume the compiler is implemented correctly! > > > > Next I find some of the logic of your arguments here very weak. > > > Paraphrasing. We have trouble testing safety critical systems, but we > > > will use them anyway. > > > > If you have trouble with the argument, "real-world safety critical > > systems > > are difficult to develop and qualify," then I recommend you stay away > > from all real-world safety critical systems. > > > > More to the point, the "paraphrasing" misses the argument. Here is > > a better summary. "Keep it simple, stupid. Don't add complexity to the > > product or the process unless it provides the best payoff vs. all > > alternatives. Furthermore, _all_ alternatives have risks as well as > > benefits; ignore anyone who says otherwise as a religious fanatic." > > I'll agree with this point. The disagreement between us is over DBC > being an aid to improving the process. From practical experience, I > believe it does. Without quantification, all we can do is bow our heads and pray at this point. Leaving the telephone off the hook is also an aid to improving the process (this is a real result of a real study). Compare the costs and benefits of this vs. DBC. > I don't think that you have backed your arguments up with enough facts > to justify your position. Fortunately, I'm not the one advancing the assertion that DBC is the best alternative. If I were, I would be worried. > Now that is not saying your wrong, but part of > the reason for havin a vocal discusion on the point is DBC advocates > have taken an theory on board that they believe to be correct. ******* I "believe" that you have summarized my problem with your argument quite neatly. > As with > all discusion on theory, you have to come up with examples that > contradict, or a better theory. Actually, no. The burden of proof is on the group advancing the claim. All I've said is that you haven't proved your claim. But, just for fun, I did give you a cheaper alternative, so you can look at that if you want. > The contradictions either show up > missing parts of the theory, in which case it is improved, or you come > up with a new theory which is better. Actually, no. I think you dropped a few steps in the scientific method (somewhere between "pose a hypothesis" and "accept or reject hypothesis"). > Since you have strongly held > views, I want find out what they are, since they might improve mine and > others knowledge. What makes you think I have strongly held views? For that matter, what relevance is the _strength_ of the views? Sounds suspiciously like a religious argument, which I find boring. > > > > Hmmm. > > > > > > > http://www.flash.net/~kennieg/ariane.html#s3.3 > > > > > > > > There are approaches that can avoid such costs, particularly those of > > > > 3.2.2 and 3.3 (by not requiring object code modification). 3.1.6 can > > > > be mitigated through the use of techniques that minimize cost (e.g. > > > > automated structural testing analysis). > > > > I note you didn't respond to this part. Hmmm indeed! > > I'll look it up and reply. > > > > > In any case, I'm going to have a wonderful Labor Day, hope you have the > > same. Just don't build any safety-critical systems that I might end > > up using, OK? > > Your pension probably depends on it. ;-) As I do when I go flying in > Norfolk, lots of your products wizzing around the sky there. > > -- > > Nick ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract)
@ 1997-09-09 0:00 Marc Wachowitz
0 siblings, 0 replies; 132+ messages in thread
From: Marc Wachowitz @ 1997-09-09 0:00 UTC (permalink / raw)
mheaney@ni.net (Matthew Heaney) wrote:
> I've always been curious about the semantics of exception propagation,
> because it doesn't correspond to anything in pure math (or does it?). If I
> divide x by 0 on paper, I can strug my shoulders and say, "Oh well,
> division by 0 isn't defined," but on a computer, I have to do _something_.
That's easy. All functions (or generally procedures, or any statements and
expressions) can be seen as mappings from one state to another, and among
the possible outcomes of a such functions are the "normal outcome", where no
exception was raised, and some "abnormal outcome" (possibly indicating the
detailed cause for the exception as well, whether just with a name, or with
additional data, like the error code of some system call). In the area of
applicative languages, and the associated theory, there's even something
known as continuation-passing style, where any sequence of computation is
made explicit by passing to every function another function, the so-called
continuation, which is invoked with the result of the former function. Then
control structure manifests as a choice between many possible continuations.
You could model the dynamic nesting of exception handlers by passing to each
function (in the general sense; i.e. also expressions/statements) both a
continuation for normal cases and a continuation for exceptional cases, and
functions without any own exception handlers would pass along whatever they
received as their exception-continuation. When an exception handler doesn't
propagate the exception, that means that it invokes the appropriate normal
continuation of its own context.
In Scheme (a Lisp dialect), continuations are even available to programmers
and can be used to model a variety of other control structures, including
exceptions, but also backtracking or coroutines. (For detailed background,
I suggest you ask on comp.lang.scheme about these things; there are people
who can probably give you better references to books or papers on the net
than the little I'd have available.)
-- Marc Wachowitz <mw@ipx2.rz.uni-mannheim.de>
^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract)
@ 1997-09-09 0:00 Marc Wachowitz
1997-09-15 0:00 ` Joachim Durchholz
1997-09-17 0:00 ` Paul Johnson
0 siblings, 2 replies; 132+ messages in thread
From: Marc Wachowitz @ 1997-09-09 0:00 UTC (permalink / raw)
paul.johnson@gecm.com (Paul Johnson) wrote:
> In fact the Eiffel exception mechanism is superior to the Ada one
> because it is built on a theoretical model of software engineering.
It is only "superior" if you think that Bertrand Meyer's proposed theory
about exceptions is the only valid one. I don't think it is - and just to
the contrary, I consider something like Eiffel's class EXCEPTION an ugly
hack to differentiate between kinds of exceptions.
In fact, I think Common Lisp, and later C++ and Java, got it right with
using subtyping as a means to differentiate between exception objects and
to associate information with exceptions; likewise, as in Modula-3 and
Java (similarly C++, as far as I know), I'd like to have a classification
of the possible exceptions raised by a routine in its declaration. Lacking
that, Ada's solution is still far superiour to Eiffel's approach, in my
view.
-- Marc Wachowitz <mw@ipx2.rz.uni-mannheim.de>
^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 Marc Wachowitz @ 1997-09-15 0:00 ` Joachim Durchholz 1997-09-17 0:00 ` Paul Johnson 1 sibling, 0 replies; 132+ messages in thread From: Joachim Durchholz @ 1997-09-15 0:00 UTC (permalink / raw) Marc Wachowitz wrote: > ...I consider something like Eiffel's class EXCEPTION an ugly > hack to differentiate between kinds of exceptions. Indeed it is. Mimicking Java's elaborate I/O exception hierarchy would be a nightmare. However, exceptions don't have to serve as many purposes in Eiffel as in Java. First of all, Eiffel is designed for side-effect-free functions. A subroutine is either a command (procedure, function with void return type) that may change the externally perceivable state of an object. Or it is a query (function, function with non-void return type) that allows us to perceive the state of the object. This means file I/O (to most plentiful source of exceptions I think) works totally different than in Java or C. There is no getchar() function, which would change the state of the associated FILE object *and* return a value. Instead, you can have a get_file_block(from,to) procedure that tries to read the bytes in the given from..to range; if an I/O error occurs, the FILE object takes note of the error. Nothing else is done in get_file_block; however, FILE also offers a set of queries to determine wether the last access was successful, failure reasons if not, access to data as far as it could be read, etc. etc. What remains for exception handling are two sources: 1) Truly unexpected stuff, which is traditionally reported with the prefix "This can't happen:". There isn't much that can be done about such events - a human must look at the message and decide what to do - which EXCEPTION will readily handle. 2) There are a few operations where checking wether they will work before calling them is as expensive as running the operation. Typical examples are arithmetic overflow conditions and matrix inversions. In these cases, the exceptions are raised at the call and should be handled immediately after the call. Again, the services from EXCEPTION are sufficient to handle this. What I think is misdesigned is the retry mechanism - to continue after an exception, an Eiffel routine *must* restart at its beginning and successfully run through to the end. Retrying is the right answer in several cases, in particular if hardware is involved, but there are lots of other applications, and the retry mechanism makes for some ugly and needlessly complex control flows. (Which is one of the reasons why exception processing is done only if necessary, which is exactly a design goal of Eiffel - maybe the unwieldiness of retry is by design?) Regards, Joachim -- Please don't send unsolicited ads. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-09 0:00 Marc Wachowitz 1997-09-15 0:00 ` Joachim Durchholz @ 1997-09-17 0:00 ` Paul Johnson 1997-09-18 0:00 ` Robert Dewar ` (2 more replies) 1 sibling, 3 replies; 132+ messages in thread From: Paul Johnson @ 1997-09-17 0:00 UTC (permalink / raw) In article <5v34m5$pl9$1@trumpet.uni-mannheim.de>, Marc Wachowitz <mw@ipx2.rz.uni-mannheim.de> writes >paul.johnson@gecm.com (Paul Johnson) wrote: >> In fact the Eiffel exception mechanism is superior to the Ada one >> because it is built on a theoretical model of software engineering. > >It is only "superior" if you think that Bertrand Meyer's proposed theory >about exceptions is the only valid one. I don't think it is - and just to >the contrary, I consider something like Eiffel's class EXCEPTION an ugly >hack to differentiate between kinds of exceptions. Which suggests that you are missing the point about DBC. The precise mechanism by which the client distinguishes between exceptions is not important (in fact I rather agree with you about EXCEPTION). What is important is the fact that ignoring an exception is not an option. DBC requires that a class either fulfil its contract or raise an exception. The client class which recieves the exception can either try again a different way or pass the exception on to its client. Simply hiding the failure under the carpet is not an option. The precise nature of the exception is much less important than its existance. Ada allows the programmer to quietly ignore an exception and pretend that a routine succeeded when in fact it failed. This is wrong. Paul. --------------------------------+--------------------------------- Paul Johnson | You are lost in a maze of twisty Email: Paul@treetop.demon.co.uk | little standards, all different. paul.johnson@gecm.com | ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-17 0:00 ` Paul Johnson @ 1997-09-18 0:00 ` Robert Dewar 1997-09-18 0:00 ` Jon S Anthony 1997-09-18 0:00 ` Stephen Leake 2 siblings, 0 replies; 132+ messages in thread From: Robert Dewar @ 1997-09-18 0:00 UTC (permalink / raw) iPaul says <<What is important is the fact that ignoring an exception is not an option. DBC requires that a class either fulfil its contract or raise an exception. The client class which recieves the exception can either try again a different way or pass the exception on to its client. Simply hiding the failure under the carpet is not an option. The precise nature of the exception is much less important than its existance. Ada allows the programmer to quietly ignore an exception and pretend that a routine succeeded when in fact it failed. This is wrong.>> Paul, can you post a detailed Ada example that shows what you mean by the last paragraph. Without such an example, it is impossible to figure out what you think might be "wrong". ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-17 0:00 ` Paul Johnson 1997-09-18 0:00 ` Robert Dewar @ 1997-09-18 0:00 ` Jon S Anthony 1997-09-18 0:00 ` Stephen Leake 2 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-18 0:00 UTC (permalink / raw) In article <wihnDCAGPDI0IwlD@treetop.demon.co.uk> Paul Johnson <Paul@treetop.demon.co.uk> writes: > >It is only "superior" if you think that Bertrand Meyer's proposed theory > >about exceptions is the only valid one. I don't think it is - and just to > >the contrary, I consider something like Eiffel's class EXCEPTION an ugly > >hack to differentiate between kinds of exceptions. > > Which suggests that you are missing the point about DBC. Or that he sees the point and doesn't think much of it in this context. > What is important is the fact that ignoring an exception is not an > option. DBC requires that a class either fulfil its contract or raise > an exception. The client class which recieves the exception can either > try again a different way or pass the exception on to its client. > Simply hiding the failure under the carpet is not an option. The > precise nature of the exception is much less important than its > existance. OK, but the existence of the exception is not something you can just completely forget about with no effect. Either you handle it (ala' Eiffel) or you don't and then it will eventually get handled (by someone else) or fall out the bottom and halt the program. > Ada allows the programmer to quietly ignore an exception and pretend > that a routine succeeded when in fact it failed. This is wrong. How do you figure that? The only way to "quietly ignore" an exception is to explicitly handle it _by_ ignoring it: ... begin ... whatever exception when others => null; -- Dirty trick on the client, blow up but -- ignore that fact and pretend it didn't happen. end; I'm not sure how this is really any different than hacking a similar dirty trick in Eiffel where you simply pretend that things worked OK (so called, "organized panic" or it's slight variant "resumption"). And you don't need to put in any rescue clause and you just end up with the default (all the way back to ANY's which does nothing). This last is really no different at all from what happens if you have no user handlers in the Ada case. I guess the point is simply that Eiffel does not _ensure_ things will be "done right" any more than Ada does or for that matter the Java/IDL model. /Jon -- Jon Anthony STL, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-17 0:00 ` Paul Johnson 1997-09-18 0:00 ` Robert Dewar 1997-09-18 0:00 ` Jon S Anthony @ 1997-09-18 0:00 ` Stephen Leake 1997-09-18 0:00 ` Mark L. Fussell 1997-09-18 0:00 ` W. Wesley Groleau x4923 2 siblings, 2 replies; 132+ messages in thread From: Stephen Leake @ 1997-09-18 0:00 UTC (permalink / raw) Paul Johnson wrote: > > Ada allows the programmer to quietly ignore an exception and pretend > that a routine succeeded when in fact it failed. This is wrong. I assume you are talking about: begin ... some code exception when others => null; end; which ignores exceptions. Usually, this is a bad idea. But sometimes, it is essential. Consider the top level loop of a fail-safe system: loop begin Initialize; loop ... do main stuff end loop exception when others => null; end; end loop; This way, no matter what the "main stuff" does, the outer loop will try again if an unhandled exception is raised. Exiting to the "environment" would be less safe. How does Eiffel handle this situation? This is a general philosophy of Ada; provide the tools to do various jobs. Don't force a programmer to do something because it's "good". > > Paul. > --------------------------------+--------------------------------- > Paul Johnson | You are lost in a maze of twisty > Email: Paul@treetop.demon.co.uk | little standards, all different. > paul.johnson@gecm.com | -- - Stephe ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-18 0:00 ` Stephen Leake @ 1997-09-18 0:00 ` Mark L. Fussell [not found] ` <11861963wnr@eiffel.demon.co.uk> ` (2 more replies) 1997-09-18 0:00 ` W. Wesley Groleau x4923 1 sibling, 3 replies; 132+ messages in thread From: Mark L. Fussell @ 1997-09-18 0:00 UTC (permalink / raw) Stephen Leake wrote: > Paul Johnson wrote: > > Ada allows the programmer to quietly ignore an exception and pretend > > that a routine succeeded when in fact it failed. This is wrong. > > I assume you are talking about: > begin > ... some code > exception > when others => > null; > end; [SNIP] > How does Eiffel handle this situation? A close equivalent in Eiffel is the following example. This is actually a variation from the discussion in Section 12.5 of OOSC-2. is -- The Eiffel version of the above local attempts : INTEGER -- FYI: initializes attempts to 0 do if attempts = 0 then -- do main stuff else -- do nothing end rescue attempts := attempts + 1 retry end The functionality is identical to the Ada version, so it likewise "pretends to succeed when in fact it failed". The important thing to Bertrand Meyer [from my understanding] is that ONLY the main body can exit a routine without exception, so we have isolated bad contract specification and fulfillment (the body) from bad error recovery (the rescue). Quoting two relevant paragraphs: "This example [similar to above] is typical of the use of retry. The rescue clause never attempts to reach the original goal using a substitute implementation; reaching this goal, as expressed by the postcondition if there is one, is the privelege of the normal body...." "This mechanism strictly adheres to the Disciplined Exception Handling principle: either a routine succeeds, that is to say its body executes to the end and satisfies the postcondition, or it fails. When interrupted by an exception, you may either report failure or try your normal body again; in no way can you exit through the rescue clause and pretend to your caller that you succeeded." Most of the difference between the Eiffel and Ada approach is really "what it feels like" in the exception handler. Eiffel's exception handler give you a chance to retry the main body which can than do what ever it wants (within its contract), but in so doing returns you to thinking about how to satisfy the routine call. The Ada (and many other languages) approach allows you to try to both recover from the exception and satisfy the routine call in one place. This may lead you to forget to do one or both of these responsibilities. Certainly Eiffel calls out the 'do nothing' behavior more strongly by having it be in the main body: if attempts = 0 then -- do main stuff else -- do nothing end This looks much stranger and more suspicious than the equivalent: begin ... some code exception when others => null; In the quotes above, the following remark implies more than it means: "in no way can you exit through the rescue clause and pretend to your caller that you succeeded". Since the caller only sees the routine return, it would not know whether you 'pretended to succeed' via the rescue/exception clause or through the main body of the routine. Pretending to succeed is possible one way or the other. In either case, your exiting normally implies you fulfilled your contract (post-condition) and if Ada had post-conditions then: when others => null; should have to satisfy them or throw a new exception. To be fair, the sentence before BM defined 'succeed' more restrictively as the execution of the body, but that definition is Eiffel specific and the word 'success' has a more general connotation. --Mark mark.fussell@chimu.com i ChiMu Corporation Architectures for Information h M info@chimu.com Object-Oriented Information Systems C u www.chimu.com Architecture, Frameworks, and Mentoring ^ permalink raw reply [flat|nested] 132+ messages in thread
[parent not found: <11861963wnr@eiffel.demon.co.uk>]
* Re: Building blocks (Was: Design By Contract) [not found] ` <11861963wnr@eiffel.demon.co.uk> @ 1997-09-19 0:00 ` Mark L. Fussell 0 siblings, 0 replies; 132+ messages in thread From: Mark L. Fussell @ 1997-09-19 0:00 UTC (permalink / raw) The following extracts salient thread pieces from Paul Johnson, Stephen Leake, Roger Browne, and myself. > > Paul Johnson wrote: > > > Ada allows the programmer to quietly ignore an exception and pretend > > > that a routine succeeded when in fact it failed. This is wrong. Mark L. Fussell <mark.fussell@chimu.com> writes: [SNIPPED Eiffel Equivalent of Ada Exception] > > The functionality [of the Eiffel version] > > is identical to the Ada version, so it likewise > > "pretends to succeed when in fact it failed". The important thing to > > Bertrand Meyer [from my understanding] is that ONLY the main body can > > exit a routine without exception... Roger Browne wrote: > ..and therefore it must meet the postcondition of that routine, else > it triggers a further exception (a "routine failure" exception). > > So, to the extent that the contract can be coded into the postcondition, > this example does not "pretend to succeed when in fact it failed". And the Ada and Eiffel examples are equivalent from the caller's point of view: exactly the same state was reached when the routine returns. So we have refuted the concept that Ada routines are "flawed" and can 'pretend to succeed' (via "ignoring" exceptions) where Eiffel routines can not. Either both succeeded or both failed. Either both can pretend to succeed (by not throwing an exception when the contract is not fulfilled) or neither can. Two differences are (1) Eiffel has postconditions and could better (automatically) recognize failure which would reduce 'pretending'. And (2) the feel of the code is different, possibly leading to focusing more on fulfilling the contract and recognizing when you can not. These may be good (even superior) things in Eiffel but they don't make Ada's exception mechanism "wrong" or flawed. --Mark mark.fussell@chimu.com i ChiMu Corporation Architectures for Information h M info@chimu.com Object-Oriented Information Systems C u www.chimu.com Architecture, Frameworks, and Mentoring ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-18 0:00 ` Mark L. Fussell [not found] ` <11861963wnr@eiffel.demon.co.uk> @ 1997-09-19 0:00 ` Jon S Anthony 1997-09-23 0:00 ` Mark L. Fussell 1997-09-19 0:00 ` Robert A Duff 2 siblings, 1 reply; 132+ messages in thread From: Jon S Anthony @ 1997-09-19 0:00 UTC (permalink / raw) In article <3421E190.49CC@chimu.com> "Mark L. Fussell" <mark.fussell@chimu.com> writes: > is > -- The Eiffel version of the above > local > attempts : INTEGER -- FYI: initializes attempts to 0 > do > if attempts = 0 then > -- do main stuff > else > -- do nothing > end > rescue > attempts := attempts + 1 > retry > end > Most of the difference between the Eiffel and Ada approach is really > "what it feels like" in the exception handler. That sounds "right" to me. > Eiffel's exception handler give you a chance to retry the main body > which can than do what ever it wants (within its contract), but in > so doing returns you to thinking about how to satisfy the routine > call. The Ada (and many other languages) approach allows you to try > to both recover from the exception and satisfy the routine call in > one place. This may lead you to forget to do one or both of these > responsibilities. Is the Eiffel approach really conceptually different from a recursive "retry" (where the Eiffel retry is basically a structured goto the beginning of the current invocation)? For example, procedure P (.... Attempts : Natural := 0) is ... if Attempts = 0 then -- do main stuff else -- do nothing end; exception when others => -- (or more specific exception...) P(....Attempts+1) ... end P; /Jon -- Jon Anthony STL, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-19 0:00 ` Jon S Anthony @ 1997-09-23 0:00 ` Mark L. Fussell 0 siblings, 0 replies; 132+ messages in thread From: Mark L. Fussell @ 1997-09-23 0:00 UTC (permalink / raw) To: Jon S Anthony Jon S Anthony wrote: ... > Is the Eiffel approach really conceptually different from a recursive > "retry" (where the Eiffel retry is basically a structured goto the > beginning of the current invocation)? For example, > > procedure P (.... Attempts : Natural := 0) is > ... > if Attempts = 0 then > -- do main stuff > else > -- do nothing > end; > exception > when others => -- (or more specific exception...) > P(....Attempts+1) > ... > end P; I agree that this is pretty similar to my/OOSC-2s example. The obvious difference is you have publicly exposed the 'attempts' variable which is an implementation detail, but of course this could be hidden through a second, private procedure/feature that is delegated to. And the general case could have 0..N state variables passed back in. The more important [IMO] difference is the 'feel' again. The above code shows the flexibility in exception handling that Eiffel consciously chose to disallow: having anything other than the current invocation's main body 'continue' from an exception. So the above code functions almost identically to the Eiffel code but it implies the possibility of a different solution (different responsibility) which Eiffel never would. Whether you view this as a guiding hand or hand-cuffs is probably very subjective. I doubt there is any empirical evidence that this particular Eiffel restriction produces better software[1], but it obviously does fit in well with Eiffel as a whole as it came from the same mind. --Mark mark.fussell@chimu.com [1] In my previous post I guessed at what it might help with: returning you to thinking about how to satisfy the routine call after you recover from the exception itself. You certainly have to jump through an extra hoop to carelessly ignore an exception: you don't have the Java/C++/standard short-circuit construct: try { ... } catch (Exception e) {}; But as multiple people have noted, there is a time for everything, and the above construct can be useful, for example, if you have a valid state before the 'try' and nothing within the 'try' will invalidate it (i.e. it will only move to another valid state or not at all). So we always return to the same meta-question: when should programmers be free but disciplined and when should they be confined? What tradeoffs are appropriate in each context? Hmmm... should be a 'Pattern' for this somewhere out there. i ChiMu Corporation Architectures for Information h M info@chimu.com Object-Oriented Information Systems C u www.chimu.com Architecture, Frameworks, and Mentoring ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-18 0:00 ` Mark L. Fussell [not found] ` <11861963wnr@eiffel.demon.co.uk> 1997-09-19 0:00 ` Jon S Anthony @ 1997-09-19 0:00 ` Robert A Duff 1997-09-20 0:00 ` Joachim Durchholz 2 siblings, 1 reply; 132+ messages in thread From: Robert A Duff @ 1997-09-19 0:00 UTC (permalink / raw) In article <3421E190.49CC@chimu.com>, Mark L. Fussell <mark.fussell@chimu.com> wrote: >A close equivalent in Eiffel is the following example. This is actually >a variation from the discussion in Section 12.5 of OOSC-2. I read about this in OOSC-1, and I didn't buy it. It seems to me that retry has nothing at all to do with whether an operation can "pretend it succeeded". The thing that prevents that pretense is having a spec for what the routine in supposed to do. In Eiffel, this is represented by the postcondition and invariant (which may include executable boolean expressions, plus comments). In Ada, it's represented mainly by comments, but perhaps also by constraints, and maybe even raise_statements in the code. If Eiffel had Ada-style exception handlers, I don't see how this would do any damage. The exception handler would still be required to obey the postcondition. Either way, there's always the danger that the programmer forgot to handle some case correctly. But that's true even without exceptions: if <some condition> then <correct code> else <wrong code> end if; If <some condition> is usually True, and your test cases fail to exercise the else branch, then you have a bug that a customer might trip over. Likewise, if the main body of a procedure is right, but the exception handler is wrong, you have a bug. Either way, the post condition will catch it at run time. I don't see how "retry" enhances the ability of postconditions to find bugs. Furthermore, retry seems to have all the bad properties of goto. And the worst sort of goto -- the kind that jumps backwards in the code, forming a loop, without actually writing "loop" at the front. >is > -- The Eiffel version of the above >local > attempts : INTEGER -- FYI: initializes attempts to 0 >do > if attempts = 0 then > -- do main stuff > else > -- do nothing > end >rescue > attempts := attempts + 1 > retry >end The above code seems obfucatory to me. If you really want to retry, I would much rather have an explicit loop: loop begin ... -- do main stuff exit; exception when Some_Error => null; end; end loop; Often, you want to do something *different* when the exception occurs (still, of course, obeying the postcondition). That's what the above Eiffel code does, but in a confusing way. There's no warning at the top of the code that we might be entering it from the exception handler. In that regard, retry is *worse* than a goto -- at least with a backward goto there's a label there warning you that some other thing might jump here. It seems much clearer to say "do THIS in the normal case, but if you get an exception, do THAT instead". And of course, THIS and THAT must obey postconditions. >"This mechanism strictly adheres to the Disciplined Exception Handling >principle: either a routine succeeds, that is to say its body executes >to the end and satisfies the postcondition, or it fails. This is a bogus definition of "succeed". The only sensible definition is "obeys the postcondition". And that could be achieved just as well without retry. >... When >interrupted by an exception, you may either report failure or try your >normal body again; in no way can you exit through the rescue clause and >pretend to your caller that you succeeded." But if exception handling were more Ada-like, it would *still* be the case that "in no way can you ... pretend ...". You would still be required to obey the postcondition. >Most of the difference between the Eiffel and Ada approach is really >"what it feels like" in the exception handler. Eiffel's exception >handler give you a chance to retry the main body which can than do what >ever it wants (within its contract), but in so doing returns you to >thinking about how to satisfy the routine call. The Ada (and many other >languages) approach allows you to try to both recover from the exception >and satisfy the routine call in one place. This may lead you to forget >to do one or both of these responsibilities. Just the opposite, IMHO. With retry, you might forget, when writing the main body, that you might get there via retry. With the Ada approach, you know which situation you're in, and you can write code that satisfies the postcondition on that basis -- no need for bogus state variables like the above "attempts", which seem to obfuscate. >Certainly Eiffel calls out the 'do nothing' behavior more strongly by >having it be in the main body: > if attempts = 0 then > -- do main stuff > else > -- do nothing > end >This looks much stranger and more suspicious than the equivalent: > begin > ... some code > exception > when others => > null; I disagree. Unless the "when others => null;" is inside a loop (which I prefer to indicate by saying "loop", rather than the goto-ish backwards jump of "retry"), it looks mightily suspicious to me. On the other hand, in the Eiffel case, if the main body simply said "do main stuff" (without the if statement), then it seems easier to forget that we might get here with attempts > 0. >In the quotes above, the following remark implies more than it means: >"in no way can you exit through the rescue clause and pretend to your >caller that you succeeded". Since the caller only sees the routine >return, it would not know whether you 'pretended to succeed' via the >rescue/exception clause or through the main body of the routine. >Pretending to succeed is possible one way or the other. Exactly. >...In either case, >your exiting normally implies you fulfilled your contract >(post-condition) and if Ada had post-conditions then: > when others => null; >should have to satisfy them or throw a new exception. To be fair, the >sentence before BM defined 'succeed' more restrictively as the execution >of the body, but that definition is Eiffel specific and the word >'success' has a more general connotation. Agreed. In summary, I think it's postconditions that help make routines work properly in all cases (including exceptional cases). I don't see any way in which "retry" helps ensure that postconditions are obeyed, and I think retry simply makes the code more confusing. - Bob ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-19 0:00 ` Robert A Duff @ 1997-09-20 0:00 ` Joachim Durchholz 1997-09-22 0:00 ` Matthew Heaney ` (3 more replies) 0 siblings, 4 replies; 132+ messages in thread From: Joachim Durchholz @ 1997-09-20 0:00 UTC (permalink / raw) Robert A Duff wrote: > The exception handler would still be required to obey > the postcondition. With the exception that postconditions (even if you writen them down as raise_statements) aren't handled as well as in Eiffel: They aren't automatically included in the package documentation, and they aren't automatically inherited by descendants (if it's a tagged type). > Either way, there's always the danger that the > programmer forgot to handle some case correctly. Agreed. > Furthermore, retry seems to have all the bad properties of goto. And > the worst sort of goto -- the kind that jumps backwards in the code, > forming a loop, without actually writing "loop" at the front. I don't particularly like the semantics of retry. I've already seen Eiffel code that was so obfuscated by squeezing the error handling logic into a loop that it was actually wrong. And the author was actually one of the Big Names in the Eiffel community... Personally, I'd prefer the C++/Java style: try -- code that may raise an exception on <exception identification> do -- exception handler on <other exception id> do ... end (ad-hoc syntax). I don't like the Ada solution either. It is "structured" in that it will resume execution at the point where the execution occurred, but that's *very* wrong. The exception handler can't know at which point in the code the exception occurred (maybe even in a subroutine!), so it can't know what to do to fix the problem. The Eiffel solution is marginally better - it says "if it don't work, don't try to fix it, try again if there is anything to do about it". This policy isn't wrong, but it doesn't cover all cases where an exception might be raised. [good examples of obfuscated retry statements snipped] > >"This mechanism strictly adheres to the Disciplined Exception > Handling > >principle: either a routine succeeds, that is to say its body > executes > >to the end and satisfies the postcondition, or it fails. > > This is a bogus definition of "succeed". The only sensible definition > is "obeys the postcondition". And that could be achieved just as well > without retry. Yup. Though Ada has no formal connection to postconditions, so it doesn't offer us guidelines what to do about an exception. What's disciplined about Eiffel exceptions is not the retry instruction, which is somewhat secondary. The discipline of exception handling in Eiffel has other sources: - A precise definition of what an exception indicates (namely a routine that fails to fulfill its postcondition - other languages, lacking the notion of postcondition, can't even start to compete) - A strict guideline when to raise an exception explicitly: if something uncontrollable happens that makes fulfilling a postcondition imnpossible. Such uncontrollable events are: actions by concurrent threads, bugs, unhandled exceptions in called routines, and algorithms where controlling the problems is nearly as expensive as just trying (like in matrix inversion, where determining wether a matrix is invertible takes nearly as long as just starting the inversion and aborting if a division by zero occurs). - A strong guideline *not* to use exceptions as interprocedural goto. (I'm pretty sure that this is frowned upon by all serious Ada shops, but it's still a difference if such a guideline is expressed in all textbooks from the beginning of if you have to install such a policy. I call such conventions "language culture" - it's not part of the formal specification, but important enough to strongly influence the average quality of programs written in a language.) > In summary, I think it's postconditions that help make routines work > properly in all cases (including exceptional cases). I don't see any > way in which "retry" helps ensure that postconditions are obeyed, and > I > think retry simply makes the code more confusing. Right. Regards, Joachim -- Please don't send unsolicited ads. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-20 0:00 ` Joachim Durchholz @ 1997-09-22 0:00 ` Matthew Heaney 1997-09-23 0:00 ` Veli-Pekka Nousiainen 1997-09-23 0:00 ` Joachim Durchholz 1997-09-23 0:00 ` Jon S Anthony ` (2 subsequent siblings) 3 siblings, 2 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-22 0:00 UTC (permalink / raw) In article <3423BE13.9C3852A4@munich.netsurf.de>, Joachim Durchholz <joachim.durchholz@munich.netsurf.de> wrote: >I don't like the Ada solution either. It is "structured" in that it will >resume execution at the point where the execution occurred, but that's >*very* wrong. The exception handler can't know at which point in the >code the exception occurred (maybe even in a subroutine!), so it can't >know what to do to fix the problem. I don't understand what you mean by "resume execution at the point where the execution [exception?] occurred," because Ada does NOT resume execution at the point of the exception. Rather, normal execution is abandoned, and control passes to the exception handler. You are correct in stating that the exception handler can't know at which point the exception occured, but only if there is a "large" amount of program text covered by a handler, and there is more the one place where the exception can occur. The solution in this case is to localize handling of the exception, so that it isn't ambiguous: begin X := new T; exception when Storage_Error => raise Stack_Full; end; >Though Ada has no formal connection to postconditions, so it doesn't >offer us guidelines what to do about an exception. While it's true that Ada syntax does not include a mechanism of specifying which exceptions can be raised by a subprogram, I wouldn't say that there are "no guidelines" for what to do about an exception. You simply state - in the form of a comment - which exceptions can be raised by a subprogram, and handle them as appropriate. >What's disciplined about Eiffel exceptions is not the retry instruction, >which is somewhat secondary. The discipline of exception handling in >Eiffel has other sources: >- A precise definition of what an exception indicates (namely a routine >that fails to fulfill its postcondition - other languages, lacking the >notion of postcondition, can't even start to compete) This statement confuses syntax with semantics. By a very deliberate choice during language design, there is not always a way in Ada to state syntactically what the postcondition of a subprogram is (and never any way to state what exceptions are propagated by a subprogram). However, in Ada, you do state what the postcondition is, in the form of a comment. It is clearly not the case that Ada - or any other language - "lacks a notion of postcondition." So yes, in Ada, you really do raise an exception when you are unable to satisfy a postcondition, it's just that the postcondition and possible exceptions raised cannot be stated as part of Ada syntax; they must be stated as a comment. Of course, there's nothing to prevent a programmer from failing to fulfill his postcondition, or from raising exceptions he hasn't advertised, just as there is no way to prevent a programmer from returning the value of the cosine from a function called Sin. But this is a programmer problem, not an Ada problem. >- A strict guideline when to raise an exception explicitly: if something >uncontrollable happens that makes fulfilling a postcondition >imnpossible. Such uncontrollable events are: actions by concurrent >threads, bugs, unhandled exceptions in called routines, and algorithms >where controlling the problems is nearly as expensive as just trying >(like in matrix inversion, where determining wether a matrix is >invertible takes nearly as long as just starting the inversion and >aborting if a division by zero occurs). This is the same guideline one uses in Ada. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-22 0:00 ` Matthew Heaney @ 1997-09-23 0:00 ` Veli-Pekka Nousiainen 1997-10-03 0:00 ` Robert I. Eachus 1997-09-23 0:00 ` Joachim Durchholz 1 sibling, 1 reply; 132+ messages in thread From: Veli-Pekka Nousiainen @ 1997-09-23 0:00 UTC (permalink / raw) Matthew Heaney <mheaney@ni.net> wrote in article <mheaney-ya023680002209971930310001@news.ni.net>... > In article <3423BE13.9C3852A4@munich.netsurf.de>, Joachim Durchholz > <joachim.durchholz@munich.netsurf.de> wrote: > <SNIP> > > >What's disciplined about Eiffel exceptions is not the retry instruction, > >which is somewhat secondary. The discipline of exception handling in > >Eiffel has other sources: > >- A precise definition of what an exception indicates (namely a routine > >that fails to fulfill its postcondition - other languages, lacking the > >notion of postcondition, can't even start to compete) > > This statement confuses syntax with semantics. By a very deliberate choice > during language design, > there is not always a way in Ada to state syntactically what the > postcondition of a subprogram is (and never any way to state what > exceptions are propagated by a subprogram). However, in Ada, you do state > what the postcondition is, in the form of a comment. It is clearly not the > case that Ada - or any other language - "lacks a notion of postcondition." It is clear to me that postconditioning is missing in all other languages exept Eiffel (Sather???). If all you need is comments, then my old hex-assembler for an 8-bit processor is all O-O with DbC, I just comment :-) > > So yes, in Ada, you really do raise an exception when you are unable to > satisfy a postcondition, it's just that the postcondition and possible > exceptions raised cannot be stated as part of Ada syntax; they must be > stated as a comment. > <SNIP> > IMO -- ------------------------------------------------------------------------- Veli-Pekka Nousiainen Sokinsuontie 3 A 1, FIN-02760 Espoo, Finland TEL +358-9-859 2025 ; GSM 0400-5940 824 e-mail: vp.nousiainen@remove_this_eiffel.fi ------------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-23 0:00 ` Veli-Pekka Nousiainen @ 1997-10-03 0:00 ` Robert I. Eachus 1997-10-04 0:00 ` Paul Johnson 0 siblings, 1 reply; 132+ messages in thread From: Robert I. Eachus @ 1997-10-03 0:00 UTC (permalink / raw) In article <01bcc7f6$638b7f60$108142c1@Yeif-1.eiffel.fi> "Veli-Pekka Nousiainen" <vp.nousiainen@remove_this_eiffel.fi> writes: > It is clear to me that postconditioning is missing in all other languages > exept Eiffel (Sather???). If all you need is comments, then my old > hex-assembler for an 8-bit processor is all O-O with DbC, I just comment... Actually Ada does have a quite well defined concept of pre- and post- conditions for subprograms. However, they are implicit rather than defined as part of the syntax. This guarentees that the conditions are always true, but it makes it hard to add complex postconditions. for example: subtype NNFloat is range 0..Float'Last; function Square_Root(F: in NNFloat) return NNFloat; guarentees that if no exception is raised that F is non-negative (pre-condition) and the return value is also non-negative. It also promises that all task depending on Square_Root have terminated, that all Controlled objects within Square_Root have been finalized, etc. Note that this second group of post-conditions is true whether or not an exception is raised, unless, of course, the finalization action raises an exception not handled locally--very bad form. However, defining types and subtypes is Ada is a much more awkward way of checking different postconditions than is possible in Eiffel. And also, the definitions of the subtypes and the body of the subprogram are often distant from the declaration. Thus the habit/practice of documenting the actual pre and post conditions in comments when not obvious from the declaration. Which is better? I prefer the Ada approach, where you can, with a little bit of caution, always count on the value of the object meeting all of the rules for such objects, rather than associating the conditions with the last subprogram called. However in both Ada and Eiffel, the normal case is that the post-conditions for operations of a class or type are all identical. In that case, it matters little which approach is used. -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-03 0:00 ` Robert I. Eachus @ 1997-10-04 0:00 ` Paul Johnson 1997-10-14 0:00 ` Robert I. Eachus 0 siblings, 1 reply; 132+ messages in thread From: Paul Johnson @ 1997-10-04 0:00 UTC (permalink / raw) In article <EACHUS.97Oct3164342@spectre.mitre.org>, "Robert I. Eachus" <eachus@spectre.mitre.org> writes > Actually Ada does have a quite well defined concept of pre- and >post- conditions for subprograms. However, they are implicit rather >than defined as part of the syntax. This guarentees that the >conditions are always true, but it makes it hard to add complex >postconditions. Yes, sort of. [Positive subrange example deleted] The problem is that it doesn't let you say things like item: T is require not empty > Which is better? I prefer the Ada approach, where you can, with a >little bit of caution, always count on the value of the object meeting >all of the rules for such objects, You can count on it for Eiffel as well: invariants state this kind of thing. Paul. --------------------------------+--------------------------------- Paul Johnson | You are lost in a maze of twisty Email: Paul@treetop.demon.co.uk | little standards, all different. paul.johnson@gecm.com | ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-04 0:00 ` Paul Johnson @ 1997-10-14 0:00 ` Robert I. Eachus 0 siblings, 0 replies; 132+ messages in thread From: Robert I. Eachus @ 1997-10-14 0:00 UTC (permalink / raw) In article <J87JkUA6zdN0Iwrm@treetop.demon.co.uk> Paul Johnson <Paul@treetop.demon.co.uk> writes: > The problem is that it doesn't let you say things like > item: T is > require > not empty Actually Ada does allow this type of restriction as well but only for certain classes of types. (I said:) > Which is better? I prefer the Ada approach, where you can, with a >little bit of caution, always count on the value of the object meeting >all of the rules for such objects, (Back to Paul:) > You can count on it for Eiffel as well: invariants state this kind of > thing. Not quite. The difference is that in Eiffel, invariants are checked at discrete points, while in Ada the corresponding checks occur before each assignment, so that a valid object never becomes invalid. Now, as such this is not a criticism of the Eiffel approach. There is a lot of code you couldn't write if some checks were done when components of an object were modified. With the Ada approach, you have to do a whole record assignment if you change the discriminant of a record, so there is the overhead of creating and copying the new value, even if it is only slightly different from the old. As a result, you end up designing your objects differently for the two different approaches. I prefer the designs which match the Ada idiom, where the structural effects of this are at a very low level. But it is just that, a preference. (And yes, I have had cases where the "pure" Ada design worked just fine, but had horrible performance. The fixes often include things like replacing an array of records with an array of pointers to records, or vice-versa. But the nice feature is that you can make these low level performance changes AFTER debugging your code. You may be removing some of the lifeboats, but at least they were there when you tested the package initially.) -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-22 0:00 ` Matthew Heaney 1997-09-23 0:00 ` Veli-Pekka Nousiainen @ 1997-09-23 0:00 ` Joachim Durchholz 1 sibling, 0 replies; 132+ messages in thread From: Joachim Durchholz @ 1997-09-23 0:00 UTC (permalink / raw) Matthew Heaney wrote: > > In article <3423BE13.9C3852A4@munich.netsurf.de>, Joachim Durchholz > <joachim.durchholz@munich.netsurf.de> wrote: > > I don't understand what you mean by "resume execution at the point > where > the execution [exception?] occurred," because Ada does NOT resume ^ yes that's what I meant > execution > at the point of the exception. Rather, normal execution is abandoned, > and > control passes to the exception handler. Sorry, I take that point back. There was a mental mix-up involved. > You are correct in stating that the exception handler can't know at > which > point the exception occured, but only if there is a "large" amount of > program text covered by a handler, and there is more the one place > where > the exception can occur. The solution in this case is to localize > handling > of the exception, so that it isn't ambiguous: Agreed. > >Though Ada has no formal connection to postconditions, so it doesn't > >offer us guidelines what to do about an exception. > > While it's true that Ada syntax does not include a mechanism of > specifying > which exceptions can be raised by a subprogram, I wouldn't say that > there > are "no guidelines" for what to do about an exception. You simply > state - > in the form of a comment - which exceptions can be raised by a > subprogram, > and handle them as appropriate. Hmm... that's exactly what I mean. I'm sure your shop has conventions on what form these comments should take, but other shops might have different forms. So you have to train every new programmer to write the "right" comments. So you can't sell a database that collects the exception information. There are *many* advantages to have a fixed syntactical place to place the postconditions. > >What's disciplined about Eiffel exceptions is not the retry > instruction, > >which is somewhat secondary. The discipline of exception handling in > >Eiffel has other sources: > >- A precise definition of what an exception indicates (namely a > routine > >that fails to fulfill its postcondition - other languages, lacking > the > >notion of postcondition, can't even start to compete) > > This statement confuses syntax with semantics. Huh? A postcondition has a very real semantics in Eiffel. The syntax is just that - syntax that's necessary to indicate the compiler what these boolean expressions are about. [Stuff on not formalizing the set of possible exceptions for Ada snipped.] > It is clearly > not the > case that Ada - or any other language - "lacks a notion of > postcondition." Oh yes it does. In the same way as assembler lacks the notion of parameter type - yes you can emulate it by heavy commenting and adhering to informal guidelines, but then the notion is not implemented in the language, it is implemented in the programming organization around that language. > Of course, there's nothing to prevent a programmer from failing to > fulfill > his postcondition, or from raising exceptions he hasn't advertised, > just as > there is no way to prevent a programmer from returning the value of > the > cosine from a function called Sin. But this is a programmer problem, > not > an Ada problem. Yup. And nothing will prevent an Eiffel programmer from doing the same. However, such errors are more obtrusive in an Eiffel class. Eiffel routines are typically very short, so a mismatch between a routine body and its postcondition is often obvious at the first casual glance. (Of course most programmers will see that even before writing the bug, so not many bugs of this type manifest themselves to begin with.) > >- A strict guideline when to raise an exception explicitly: if > something > >uncontrollable happens that makes fulfilling a postcondition > >imnpossible. Such uncontrollable events are: actions by concurrent > >threads, bugs, unhandled exceptions in called routines, and > algorithms > >where controlling the problems is nearly as expensive as just trying > >(like in matrix inversion, where determining wether a matrix is > >invertible takes nearly as long as just starting the inversion and > >aborting if a division by zero occurs). > > This is the same guideline one uses in Ada. It's the guideline that *should* be used in Ada. But I'd bet it isn't always followed - with pressing deadlines and less-than-perfect programmers in the shop, you can't be sure that your company's guidelines will always be followed to the letter or (more importantly) in spirit. In Eiffel, letter and spirit are the same, and the policy is already enforced by the compiler. Regards, Joachim -- Please don't send unsolicited ads. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-20 0:00 ` Joachim Durchholz 1997-09-22 0:00 ` Matthew Heaney @ 1997-09-23 0:00 ` Jon S Anthony 1997-09-24 0:00 ` Alan E & Carmel J Brain 1997-09-24 0:00 ` Richard A. O'Keefe 3 siblings, 0 replies; 132+ messages in thread From: Jon S Anthony @ 1997-09-23 0:00 UTC (permalink / raw) In article <3423BE13.9C3852A4@munich.netsurf.de> Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes: > I don't like the Ada solution either. It is "structured" in that it will > resume execution at the point where the execution occurred, but that's > *very* wrong. The exception handler can't know at which point in the > code the exception occurred (maybe even in a subroutine!), so it can't > know what to do to fix the problem. ??? What do you mean here? Surely it is clear enough that Ada does not support resumption semantics in exception handling. So, you must have something in mind here, but I can't figure out what it is... /Jon -- Jon Anthony STL, Belmont, MA 02178, 617.484.3383 "Nightmares - Ha! The way my life's been going lately, Who'd notice?" -- Londo Mollari ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-20 0:00 ` Joachim Durchholz 1997-09-22 0:00 ` Matthew Heaney 1997-09-23 0:00 ` Jon S Anthony @ 1997-09-24 0:00 ` Alan E & Carmel J Brain 1997-09-25 0:00 ` Anonymous 1997-09-24 0:00 ` Richard A. O'Keefe 3 siblings, 1 reply; 132+ messages in thread From: Alan E & Carmel J Brain @ 1997-09-24 0:00 UTC (permalink / raw) Joachim Durchholz wrote: > Personally, I'd prefer the C++/Java style: > try > -- code that may raise an exception > on <exception identification> do > -- exception handler > on <other exception id> do > ... > end > (ad-hoc syntax). > > I don't like the Ada solution either. It is "structured" in that it will > resume execution at the point where the execution occurred, but that's > *very* wrong. The exception handler can't know at which point in the > code the exception occurred (maybe even in a subroutine!), so it can't > know what to do to fix the problem. Eh??? The syntax for Ada looks like: procedure WhatEver is begin -- statements -- more statements -- end of normal execution exception when SOME_ERROR => do something; when SOME_OTHER_ERROR => do something else; when others => raise; -- just propogate to caller end WhatEver; There is no resumption! Any exception raised between the "begin" and "exception" immediately causes abandonment of normal execution, like a GOTO, to the exception block. If you want to resume, or retry, or whatever, you need to confine the exception to it's own block. A typical example looks something like: (Declarations, Constants omitted for simplicity) UnTransmitted := true; ReTryCounter := 0; while UnTransmitted loop if ReTryCounter > MaxRetries then raise LineContinuouslyBusy; end if; -- Line Too busy -- Report this upwards Transmission_Attempt_Block : begin Ethernet.TryToTransmit; UnTransmitted := false; -- Successful Transmission exception when Ethernet.LINE_BUSY => ReTryCounter := ReTryCounter+1; -- Try again -- Note that this 'handles' -- the exception when Ethernet.NACK => Untransmitted := false; -- Ignore Negative Ack. -- Again, exception handled. when others => raise; -- something unexpected and Nasty, Propagate it out! end Transmission_Attempt_Block; end loop; Note that the LINE_BUSY exception, declared in package ETHERNET is normal, expected, and handlable locally, at least up to a point. Any other exceptions coming from a call to Ethernet.TryToTransmit will be propagated upwards and outwards: there is not enough data locally to determine what to do here. Similarly, if the line is continuously busy, an exception stating this is propagated upwards. In the case of a NACK exception, cross fingers, hope it's OK, etc. Normally a VERY bad idea, but on hardware which gives 30% or more false positives, it may be the only way to go. Personally, I like the flexibility. -- aebrain@dynamite.com.au <> <> How doth the little Crocodile | Alan & Carmel Brain| xxxxx Improve his shining tail? | Canberra Australia | xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM abrain@cs.adfa.oz.au o OO*O^^^^O*OO o oo oo oo oo By pulling MAERKLIN Wagons, in 1/220 Scale ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-24 0:00 ` Alan E & Carmel J Brain @ 1997-09-25 0:00 ` Anonymous 1997-09-30 0:00 ` Alan E & Carmel J Brain 0 siblings, 1 reply; 132+ messages in thread From: Anonymous @ 1997-09-25 0:00 UTC (permalink / raw) <5v34m5$pl9$1@trumpet.uni-mannheim.de> <wihnDCAGPDI0IwlD@treetop.demon.co.uk> <34215E3D.77AE@gsfc.nasa.gov> <3421E190.49CC@chimu.com> <EGrz21.GoG@world.std.com> <3423BE13.9C3852A4@munich.netsurf.de> On Wed, 24 Sep 1997 23:55:02 -0700, Alan E & Carmel J Brain <aebrain@dynamite.com.au> wrote: >[...] > If you want to resume, or retry, or whatever, you need to confine the > exception to it's own block. A typical example looks something like: > > (Declarations, Constants omitted for simplicity) > > UnTransmitted := true; > ReTryCounter := 0; > > while UnTransmitted loop > > if ReTryCounter > MaxRetries then > raise LineContinuouslyBusy; end if; -- Line Too busy > -- Report this upwards > Transmission_Attempt_Block : > begin > > Ethernet.TryToTransmit; > UnTransmitted := false; -- Successful Transmission > > exception > when Ethernet.LINE_BUSY => > ReTryCounter := ReTryCounter+1; -- Try again > -- Note that this 'handles' > -- the exception > when Ethernet.NACK => > Untransmitted := false; -- Ignore Negative Ack. > -- Again, exception handled. > when others => raise; > -- something unexpected and Nasty, Propagate it out! > > end Transmission_Attempt_Block; > > end loop; > This doesn't seem typical to me. It differs from typical in 1. Using mixed-case identifiers instead of underline-separated identifiers (ReTryCounter instead of Re_Try_Counter). 2. Using while instead of loop/exit (ref. Ichbiah, Barnes, & Firth, "Ada Launch," 1980 Dec 10, videotape, on why while was included in the language). 3. The design of Ethernet is faulty, since it uses exceptions for non-exceptional circumstances (line busy, NACK received). 4. Unusual formatting of the if. If we have to use Ethernet as is, I'd say the following is more typical Retry_Counter := 0; Send : loop if Retry_Counter > Max_Retries then raise Line_Continuously_Busy; end if; -- Line too busy; report this upwards Try_One : begin Ethernet.Try_To_Transmit; exit Send; -- Successful transmission exception -- Try_One when Ethernet.Line_Busy => Retry_Counter := Retry_Counter + 1; -- Try again when Ethernet.Nack => exit Send; -- Accept NACK as success end Try_One; end loop Send; Jeff Carter PGP:1024/440FBE21 My real e-mail address: ( carter @ innocon . com ) "You brightly-colored, mealy-templed, cranberry-smelling, electric donkey-bottom biters." Monty Python & the Holy Grail Posted with Spam Hater - see http://www.compulink.co.uk/~net-services/spam/ ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-25 0:00 ` Anonymous @ 1997-09-30 0:00 ` Alan E & Carmel J Brain 1997-09-30 0:00 ` Matthew Heaney 1997-10-01 0:00 ` Anonymous 0 siblings, 2 replies; 132+ messages in thread From: Alan E & Carmel J Brain @ 1997-09-30 0:00 UTC (permalink / raw) Anonymous wrote: > > If you want to resume, or retry, or whatever, you need to confine the > > exception to it's own block. A typical example looks something like: > > > > (Declarations, Constants omitted for simplicity) > > > > UnTransmitted := true; > > ReTryCounter := 0; > > > > while UnTransmitted loop > > > > if ReTryCounter > MaxRetries then > > raise LineContinuouslyBusy; end if; -- Line Too busy > > -- Report this upwards > > Transmission_Attempt_Block : > > begin > > > > Ethernet.TryToTransmit; > > UnTransmitted := false; -- Successful Transmission > > > > exception > > when Ethernet.LINE_BUSY => > > ReTryCounter := ReTryCounter+1; -- Try again > > -- Note that this 'handles' > > -- the exception > > when Ethernet.NACK => > > Untransmitted := false; -- Ignore Negative Ack. > > -- Again, exception handled. > > when others => raise; > > -- something unexpected and Nasty, Propagate it out! > > > > end Transmission_Attempt_Block; > > > > end loop; > > > > This doesn't seem typical to me. It differs from typical in > > 1. Using mixed-case identifiers instead of underline-separated > identifiers (ReTryCounter instead of Re_Try_Counter). Good point, thanks for the correction. Ain't walk-through's wonderful? > 2. Using while instead of loop/exit (ref. Ichbiah, Barnes, & Firth, "Ada > Launch," 1980 Dec 10, videotape, on why while was included in the > language). I'd defend this one on style grounds, and believe the matter is religious. I have no access to this video. Any other sources? BTW perfectly willing to believe I'm wrong, I just want to know why... > 3. The design of Ethernet is faulty, since it uses exceptions for > non-exceptional circumstances (line busy, NACK received). Depends on the domain. Either of these may be exceptional (e.g. in a 1-way broadcast architecture) or normal (e.g. many nodes, all of whom may talk). > 4. Unusual formatting of the if. Style again. If expressible more clearly on one or two lines, use that, otherwise a more normal format would be if CONDITIONAL then STATEMENT; STATEMENT; end if; or even if CONDITIONAL then STATEMENT; end if; > If we have to use Ethernet as is, I'd say the following is more typical > > Retry_Counter := 0; > > Send : loop > if Retry_Counter > Max_Retries then > raise Line_Continuously_Busy; > end if; -- Line too busy; report this upwards > > Try_One : begin > Ethernet.Try_To_Transmit; > > exit Send; -- Successful transmission I'd insert a blank line here for readability and a few others, as below: > exception -- Try_One > when Ethernet.Line_Busy => > Retry_Counter := Retry_Counter + 1; -- Try again > when Ethernet.Nack => > exit Send; -- Accept NACK as success > end Try_One; > end loop Send; Makes sense to me. OTOH there is a school of thought that eschews multiple exits. But that's another story. The point is, is that both versions show in a minimum number of lines the various options one has in Ada ( -83 at least, there are more in -95), which was the basic idea. > "You brightly-colored, mealy-templed, cranberry-smelling, electric > donkey-bottom biters." Was this meant personally? (<g> added for the hard-of-thinking) If so, I take exception! (That's supposed to be a pun.... never mind...) -- aebrain@dynamite.com.au <> <> How doth the little Crocodile | Alan & Carmel Brain| xxxxx Improve his shining tail? | Canberra Australia | xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM abrain@cs.adfa.oz.au o OO*O^^^^O*OO o oo oo oo oo By pulling MAERKLIN Wagons, in 1/220 Scale ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` Alan E & Carmel J Brain @ 1997-09-30 0:00 ` Matthew Heaney 1997-09-30 0:00 ` Neil Wilson 1997-09-30 0:00 ` W. Wesley Groleau x4923 1997-10-01 0:00 ` Anonymous 1 sibling, 2 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-30 0:00 UTC (permalink / raw) In article <34316EC3.5B62@dynamite.com.au>, aebrain@dynamite.com.au wrote: >> 2. Using while instead of loop/exit (ref. Ichbiah, Barnes, & Firth, "Ada >> Launch," 1980 Dec 10, videotape, on why while was included in the >> language). > >I'd defend this one on style grounds, and believe the matter is >religious. I have no access to this video. Any other sources? BTW >perfectly willing to believe I'm wrong, I just want to know why... Yes, it's quite wrong to use a flag to terminate a while loop, instead of just using exit with a loop. The idiom is, use an exit when the termination depends on what you read, eg loop <read some data> exit when <the data has some special value> <process the data> end loop; The classic example is, read some integers until the user types in the value 0: loop Read (N); exit when N = 0; <process N> end loop; Scannars are written this way: you leave the current state when you've read something outside what you're scanning right now: Scan_Integer: loop Read (C); exit when C not in '0' .. '9'; <process this digit> end loop Scan_Integer; No, this is not a moral issue. It is a simple fact about what problem-solving strategies are best for human programmers. That the exit technique is a better "cognitive fit" was demonstrated empirically in Cognitive Strategies and Looping Constructs: An Empirical Study Elliot Soloway et al CACM Nov 83 Vol 26 Number 11, p. 853-860. From the abstract: ...Our results indicate that subjects overwhelmingly prefered a READ/PROCESS strategy over a PROCESS/READ strategy. When writing a simple looping program, those using the loop .. leave .. again construct were more often correct than those using the standard Pascal loop constructs. Here's another excerpt from an older textbook: <Greater flexibility in choosing program structures is possible if one can "exit" from a program segment "prematurely" -- that is, if one can terminate the execution of a certain segment of program before its normal completion. In the case of a DO group this means being able to terminate one particular iteration of the body [mjh: something you can't do in Ada, but can in C using "continue"], or terminate the execution of the entire DO group [mjh: "exit" in Ada or "break" in C]. In PL/I this type of exit must be accomplished by a "conditional branch."> -- from An Introduction to Programming, Richard Conway and David Gries In a recent thread on this list, we debated why Ada requires you for declare something before its use. The design philosophy of Ada - as explained in the video and to me privately by Jean Ichbiah - is that the programmer's understanding of something should only depend on what has come before. He shouldn't have to read ahead. What he needs to know to apprehend the program text only depends on the text he's already read. Your example is a classic example of how NOT to write loop, by setting a flag to false to force a while loop to terminate. The problem is that the reader of your code has to read THE ENTIRE BODY OF THE LOOP, after you've set the flag to false, to determine whether you set the flag because you want to terminate the loop right now, and whether there's more work to be done, prior to the actual end of the loop. The flag is AMBIGUOUS. If you reach a point where you need to terminate the loop, then terminate the loop, right now. Don't set a flag, execute the rest of the body, test the flag, to terminate the loop. Just terminate the loop. If you want to go from point A to point B, then go directly from point A to point B. Why go from A to C to D then to B? Especially as that may confuse the person trying to follow you. You can make the argument "this is just my style," but the whole underlying philosophy of Ada is that program text gets read by other human programmers, not just by the human who wrote it originally, and we should do as much to facilitate their understanding as possible. This means presenting information in a manner best suited for the human reader, not just the compiler. So your "style" may be the source of obfuscation and ambiguity that CONFUSE human readers of your programs. You don't live on an island. We all need to always think about the programmer playing detective who's trying to figure out what we've written. Always ask yourself as you're writing code, What can I do to make it easy for someone reading this? This is especially true when you have a choice about how to do something, and either way will work; it's called the Principle of Least Astonishment. When you reach a loop termination point, tell the human programmer reading your code, directly and unambiguously, that you want to terminate the loop, by using an exit. A loop exit is a big huge sign that tells the person reading your code that THE LOOP IS TERMINATING NOW. Nothing unambiguous about that. No more text to try to figure out. All very simple, which is precisely what we want. One more point. Among the colorful landscape of programming languages, Ada is a very conservative language. If a construct were so pernicious that it made writing correct programs difficult, or made the apprehension of program text difficult, then it wouldn't be in the language, now would it? A bunch of guys with PhDs in computer science from all over the planet voted unaminously to make Ada an international programming language standard. And _they_ all decided that exiting from a loop was OK. There's nothing extra to you need to do to make Ada programming safe, because it comes that way right out of the box. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` Matthew Heaney @ 1997-09-30 0:00 ` Neil Wilson 1997-09-30 0:00 ` Stephen Leake 1997-09-30 0:00 ` W. Wesley Groleau x4923 1 sibling, 1 reply; 132+ messages in thread From: Neil Wilson @ 1997-09-30 0:00 UTC (permalink / raw) > In article <34316EC3.5B62@dynamite.com.au>, aebrain@dynamite.com.au wrote: > Yes, it's quite wrong to use a flag to terminate a while loop, instead of > just using exit with a loop. The idiom is, use an exit when the > termination depends on what you read, eg > [SNIP] > > The classic example is, read some integers until the user types in the value 0: > > loop > > Read (N); > exit when N = 0; > > <process N> > > end loop; This can be fixed by using a 'half unroll'. Eiffel supports this: loop file.read_integer while file.last_integer != 0 x.process (file.last_integer) file.read_integer end -- loop The introduction of the syntactically redundant 'loop' marker allows you to flag the start of the loop initialisation section (technically the section that sets up the loop invariant). The 'while' section is the loop itself (which has to maintain the invariant, move forward the variant and do the correct processing). Duplicating the 'read' command can be a bit of a pain, but in many instances initialising the structure can be a different operation from the actual iteration itself. -- Neil Wilson (neil at aldur dot demon dot co dot uk) Aldur Systems Ltd, UK ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` Neil Wilson @ 1997-09-30 0:00 ` Stephen Leake 0 siblings, 0 replies; 132+ messages in thread From: Stephen Leake @ 1997-09-30 0:00 UTC (permalink / raw) Neil Wilson wrote: > [SNIP] > > > > > loop > > > > Read (N); > > exit when N = 0; > > > > <process N> > > > > end loop; > > This can be fixed by using a 'half unroll'. Eiffel supports this: why does it need to be "fixed"? what's wrong with it? > loop > file.read_integer > while file.last_integer != 0 > x.process (file.last_integer) > file.read_integer > end -- loop Yech. Where does control transfer back to when end is reached? to 'loop' or to 'while'? I'll take the Ada any day. Perhaps Eiffel does not have "exit" > > -- > Neil Wilson (neil at aldur dot demon dot co dot uk) > Aldur Systems Ltd, UK -- - Stephe ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` Matthew Heaney 1997-09-30 0:00 ` Neil Wilson @ 1997-09-30 0:00 ` W. Wesley Groleau x4923 1997-09-30 0:00 ` Matthew Heaney 1997-10-01 0:00 ` Alan E & Carmel J Brain 1 sibling, 2 replies; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-30 0:00 UTC (permalink / raw) > Yes, it's quite wrong to use a flag to terminate a while loop, > instead of just using exit with a loop. The idiom is, use an > exit when the termination depends on what you read, ..... Or to end a search when the item is found, or ... Unfortunately, there are those who feel that not identifying the loop termination at the beginning of the loop confuses the reader. These folk are supported by a non-thoughtful reading of Ada Quality and Style. The "guidelines" (we all know that's another word for "rules," right?) say to only exit from a plain loop, never from a 'while' or 'for' So folks go through wierd contortions to avoid "exit." But the accompanying explanation clearly says that _readability_ is the criteria for choosing a loop construct. -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` W. Wesley Groleau x4923 @ 1997-09-30 0:00 ` Matthew Heaney 1997-10-01 0:00 ` Alan E & Carmel J Brain 1 sibling, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-30 0:00 UTC (permalink / raw) In article <343149D9.6A30@pseserv3.fw.hac.com>, "W. Wesley Groleau x4923" <wwgrol@pseserv3.fw.hac.com> wrote: >Unfortunately, there are those who feel that not identifying the >loop termination at the beginning of the loop confuses the reader. >These folk are supported by a non-thoughtful reading of Ada Quality >and Style. Sometimes I think this book needs to be put out to pasture. >The "guidelines" (we all know that's another word for >"rules," right?) say to only exit from a plain loop, never from >a 'while' or 'for' So folks go through wierd contortions to avoid >"exit." But the accompanying explanation clearly says that >_readability_ is the criteria for choosing a loop construct. Well stated; thank you for pointing that out. The reason for any rule...um...I mean guideline is to promote understandability and ensure correctness. How often programmers forget that in their slavish adherence to a style guide! -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` W. Wesley Groleau x4923 1997-09-30 0:00 ` Matthew Heaney @ 1997-10-01 0:00 ` Alan E & Carmel J Brain 1 sibling, 0 replies; 132+ messages in thread From: Alan E & Carmel J Brain @ 1997-10-01 0:00 UTC (permalink / raw) W. Wesley Groleau x4923 wrote: > > > Yes, it's quite wrong to use a flag to terminate a while loop, > > instead of just using exit with a loop. The idiom is, use an > > exit when the termination depends on what you read, ..... > > Or to end a search when the item is found, or ... > > Unfortunately, there are those who feel that not identifying the > loop termination at the beginning of the loop confuses the reader. > These folk are supported by a non-thoughtful reading of Ada Quality > and Style. The "guidelines" (we all know that's another word for > "rules," right?) say to only exit from a plain loop, never from > a 'while' or 'for' So folks go through wierd contortions to avoid > "exit." But the accompanying explanation clearly says that > _readability_ is the criteria for choosing a loop construct. Concur. The "bottom line" is readability, that's a given (I hope..). In this case, W. Wesley Groleau has provided pursuasive evidence that my "while Unfinished" construct is less readable than his "exit" construct. Although I'm not completely convinced, I am pursuaded that the "exit" construct is superior, at least in this case. And I thought I was a true disciple of "egoless" review. There's nothing like having a bunch of people expose one's coding failings in public, calmly and correctly, to show how far one has to go. Still, I've learnt something important I didn't know before, and that's worth any amount of ego damage. My thanks to all concerned. -- aebrain@dynamite.com.au <> <> How doth the little Crocodile | Alan & Carmel Brain| xxxxx Improve his shining tail? | Canberra Australia | xxxxxHxHxxxxxx _MMMMMMMMM_MMMMMMMMM abrain@cs.adfa.oz.au o OO*O^^^^O*OO o oo oo oo oo By pulling MAERKLIN Wagons, in 1/220 Scale ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-30 0:00 ` Alan E & Carmel J Brain 1997-09-30 0:00 ` Matthew Heaney @ 1997-10-01 0:00 ` Anonymous 1997-10-01 0:00 ` Paul M Gover ` (2 more replies) 1 sibling, 3 replies; 132+ messages in thread From: Anonymous @ 1997-10-01 0:00 UTC (permalink / raw) <342A0AC6.2F2F@dynamite.com.au> <199709251320.PAA03585@basement.replay.com> On Tue, 30 Sep 1997 14:27:31 -0700, Alan E & Carmel J Brain <aebrain@dynamite.com.au> wrote: > Anonymous wrote: > [big hunk deleted] > > 2. Using while instead of loop/exit (ref. Ichbiah, Barnes, & Firth, "Ada > > Launch," 1980 Dec 10, videotape, on why while was included in the > > language). > > I'd defend this one on style grounds, and believe the matter is > religious. I have no access to this video. Any other sources? BTW > perfectly willing to believe I'm wrong, I just want to know why... This is an obscure reference, and I'd be the first to admit I've never seen this addressed anywhere else, including Barnes' book. In the video, which I had the good fortune to see in 1984, these three members of the design team give a tutorial on Ada-80 (MIL-STD-1815) with plenty of comments on "why". "While" was said to be undesireable because it tends to require the use of negative logic, which is less readable than positive logic: Read : while not End_Of_File (Fred) loop Read : loop exit Read when End_Of_File (Fred); It was included in the language for the same reason as "goto": to facilitate automated translation from languages that include the feature. Certainly "while" is preferred by those doing program correctness proofs; all the techniques for this that I have seen have been for "while" loops. Avoiding "while" does usually make for more readable code. In this specific example, "while" requires a flag variable, which is less readable than using "exit". [hunk deleted] > > 4. Unusual formatting of the if. > > Style again. If expressible more clearly on one or two lines, use that, Certainly, this is a style question. But the style used is not typical. > Makes sense to me. OTOH there is a school of thought that eschews > multiple exits. But that's another story. The point is, is that both > versions show in a minimum number of lines the various options one has > in Ada ( -83 at least, there are more in -95), which was the basic idea. I'm aware of those who think multiple exits are bad. This is something that came out of program correctness proving. However, when you look at languages that only allow a single exit from a loop (Pascal, excluding gotos) you find many common situations in which this results in unreadable code. For this reason, "exit" and the possiblity of multiple exits were included in Ada, and are considered acceptable by all competent software engineers. > > > "You brightly-colored, mealy-templed, cranberry-smelling, electric > > donkey-bottom biters." > > Was this meant personally? (<g> added for the hard-of-thinking) If so, I > take exception! (That's supposed to be a pun.... never mind...) > -- Of course this was meant personally. However, it doesn't come from me, it comes from Monty Python, so you should take exception with them. Jeff Carter PGP:1024/440FBE21 My real e-mail address: ( carter @ innocon . com ) "I fart in your general direction." Monty Python & the Holy Grail Posted with Spam Hater - see http://www.compulink.co.uk/~net-services/spam/ ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-01 0:00 ` Anonymous @ 1997-10-01 0:00 ` Paul M Gover 1997-10-04 0:00 ` Paul Johnson 1997-10-01 0:00 ` Joachim Durchholz 1997-10-02 0:00 ` Robert A Duff 2 siblings, 1 reply; 132+ messages in thread From: Paul M Gover @ 1997-10-01 0:00 UTC (permalink / raw) Anonymous wrote: > ... > > Makes sense to me. OTOH there is a school of thought that eschews > > multiple exits. But that's another story. The point is, is that both > > versions show in a minimum number of lines the various options one has > > in Ada ( -83 at least, there are more in -95), which was the basic idea. > > I'm aware of those who think multiple exits are bad. This is something > that came out of program correctness proving. However, when you look at > languages that only allow a single exit from a loop (Pascal, excluding > gotos) you find many common situations in which this results in > unreadable code. For this reason, "exit" and the possiblity of multiple > exits were included in Ada, and are considered acceptable by all > competent software engineers. > ... Some of my colleagues worked on a language which had a loop exit when end construct, but with the restriction that each loop had exactly one exit. So it didn't allow multiple exits from a loop, but still allowed: loop record = file.read() exit when file.eof() thing.accept(record) end which keeps the code readable, and prevents duplication. Does this have any impact on correctness proofs? Presumably not much, as the loop can be converted to a true while-loop by duplication. (One of the while-loop problem is that for a tidy record processing program you have to write record = file.read() Do while(~file.eof()) thing.accept(record) record = file.read() End while ) -- Paul Gover IBM Warwick Development Group Mumbling for myself, not IBM ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-01 0:00 ` Paul M Gover @ 1997-10-04 0:00 ` Paul Johnson 1997-10-04 0:00 ` Matthew Heaney 0 siblings, 1 reply; 132+ messages in thread From: Paul Johnson @ 1997-10-04 0:00 UTC (permalink / raw) In article <3432788C.E35@uk.ibm.com>, Paul M Gover <Paul_Gover@uk.ibm.com> writes >(One of the while-loop problem is that for a tidy >record processing program you have to write > record = file.read() > Do while(~file.eof()) > thing.accept(record) > record = file.read() > End while >) I know that this was an aside, but it still puzzles me. Surely it will be wrong if the file is empty: there will be no record to read. The correct version (in Eiffel) would be from file.open("foo") until file.eof loop thing.accept (file.record) end -- loop If you have to read a dummy record before file.eof becomes valid then you have a badly designed file object. Paul. --------------------------------+--------------------------------- Paul Johnson | You are lost in a maze of twisty Email: Paul@treetop.demon.co.uk | little standards, all different. paul.johnson@gecm.com | ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-04 0:00 ` Paul Johnson @ 1997-10-04 0:00 ` Matthew Heaney 1997-10-15 0:00 ` Paul Johnson 0 siblings, 1 reply; 132+ messages in thread From: Matthew Heaney @ 1997-10-04 0:00 UTC (permalink / raw) In article <PdRYMWAQ1cN0Iw4X@treetop.demon.co.uk>, Paul Johnson <Paul@treetop.demon.co.uk> wrote: >>(One of the while-loop problem is that for a tidy >>record processing program you have to write >> record = file.read() >> Do while(~file.eof()) >> thing.accept(record) >> record = file.read() >> End while >>) > >I know that this was an aside, but it still puzzles me. Surely it will >be wrong if the file is empty: there will be no record to read. The >correct version (in Eiffel) would be > > from file.open("foo") until file.eof loop > thing.accept (file.record) > end -- loop > >If you have to read a dummy record before file.eof becomes valid then >you have a badly designed file object. That's the idiom in Ada too: while not End_Of_File (F) loop Read (F, X); <do something with X>; end loop; I think the original example, though, was this: read some numbers from the user interactively, process each one at a time, and stop processing when the user enters a zero. In Ada, it would be loop Read (N); exit when N = 0; <do something with N>; end loop; This is a very clean solution, and in the Soloway paper, they showed that there were fewer errors using this loop structure compared to a loop which disallows an exit from the middle. Something like: Read (N); while N /= 0 loop <do something with N> Read (N); end loop; The issue here is that the read statement must be written twice. Exiting from the middle is a more natural idiom for certain problems. So don't assume that there's a "badly designed" file, because we might not be literally talking about a file. That the loop termination depends on what you've read (the "dummy" value) is a common occurrence, and the simplest loop idiom in this case is: loop <get value> exit when <value is special> <process value> end loop; A while loop is more complex and error prone solution for this type of problem. Soloway showed that there was a statistically significant difference between two populations, one using a test-at-the-top, and the other using a test-in-the-middle, with the latter group having fewer errors. The reference is: Coginitive Strategies and Looping Constructs: An Empirical Study Elliot Soloway et al CACM, Vol. 26, No. 11, Nov 83, p. 853 - 860 A typical example of termination depending on input is a scanner. If you're scanning an identifier (say), then you exit when you've read some whitespace: Scan_Identifier: loop <get character> exit Scan_Identifier when <char is whitespace> <buffer char> end loop Scan_Identifier; <process Identifier token> Another common idiom is a linear search. When you find the item you're looking for, bail out: Find_Item: declare Found : Boolean := False; Position : Positive range Items'Range; begin for Index in Items'Range loop if Items (Index) = Item then Position := Index; Found := True; exit; end if; end loop; if Found then <do something> else <do something else> end if; end Find_Item; Exiting from the middle of a loop also shows up in functions as an early return: function Position (Items : Item_Array; Item : T) return Natural is begin for Index in Items'Range loop if Items (Index) = Item then return Index; end if; end loop; return 0; -- means Item not found end; In none of these cases is the "file" badly designed. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-04 0:00 ` Matthew Heaney @ 1997-10-15 0:00 ` Paul Johnson 1997-10-15 0:00 ` Matthew Heaney ` (2 more replies) 0 siblings, 3 replies; 132+ messages in thread From: Paul Johnson @ 1997-10-15 0:00 UTC (permalink / raw) In article <mheaney-ya023680000410970119430001@news.ni.net>, Matthew Heaney <mheaney@ni.net> writes >In article <PdRYMWAQ1cN0Iw4X@treetop.demon.co.uk>, Paul Johnson ><Paul@treetop.demon.co.uk> wrote: >>I know that this was an aside, but it still puzzles me. Surely it will >>be wrong if the file is empty: there will be no record to read. The >>correct version (in Eiffel) would be >> >> from file.open("foo") until file.eof loop >> thing.accept (file.record) >> end -- loop [...] >I think the original example, though, was this: read some numbers from the >user interactively, process each one at a time, and stop processing when >the user enters a zero. In Ada, it would be [...] >A while loop is more complex and error prone solution for this type of >problem. Soloway showed that there was a statistically significant >difference between two populations, one using a test-at-the-top, and the >other using a test-in-the-middle, with the latter group having fewer >errors. The reference is: > >Coginitive Strategies and Looping Constructs: An Empirical Study >Elliot Soloway et al >CACM, Vol. 26, No. 11, Nov 83, p. 853 - 860 [Examples of when you want to do this in real life deleted.] Hmm. Interesting. I agree that the repeated read (or whatever instruction) before the loop and at the end is a bad idea. Quite apart from the Soloway experiment, it is duplicating code. OTOH I wonder if the situation might be reversed in real life situations with deeply nested structures. I'm rather dubious of small, neat coding experiments such as Soloway's. While they are the best handle we have on the facts, I worry that in an attempt to come up with a controllable, repeatable, and above all feasible experiment, they abstract out too much complexity. After all, it is complexity that makes programming difficult. I recall the great AT&T telephone crash in the late 80s (87?). It was caused by a bug where a programmer had mistaken the scope of a "break" instruction, and hence miscalculated the target of the resulting jump. Now thats not a statistical experiment, but its a worrying data point. I wonder what would happen if Soloway's experiment were repeated with more complex problems involving nested loops. (I haven't actually read the paper, but I'll see if our library has it tomorrow). Paul. --------------------------------+--------------------------------- Paul Johnson | You are lost in a maze of twisty Email: Paul@treetop.demon.co.uk | little standards, all different. paul.johnson@gecm.com | ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-15 0:00 ` Paul Johnson @ 1997-10-15 0:00 ` Matthew Heaney 1997-10-16 0:00 ` Joachim Durchholz 1997-10-16 0:00 ` Joachim Durchholz 1997-10-22 0:00 ` Reimer Behrends 2 siblings, 1 reply; 132+ messages in thread From: Matthew Heaney @ 1997-10-15 0:00 UTC (permalink / raw) In article <5w3FnzA6KRR0Iwt+@treetop.demon.co.uk>, Paul Johnson <Paul@treetop.demon.co.uk> wrote: >I recall the great AT&T telephone crash in the late 80s (87?). It was >caused by a bug where a programmer had mistaken the scope of a "break" >instruction, and hence miscalculated the target of the resulting jump. >Now thats not a statistical experiment, but its a worrying data point. >I wonder what would happen if Soloway's experiment were repeated with >more complex problems involving nested loops. In Ada, the programmer has control over the loop to which the exit applies, by using loop labels; the C programmer can't do this without using an explicit goto. A common idiom is to implement a finite state machine using loops, where each loop represents a different state. A "main" loop keeps the entire thing going until termination is requested. For example, I just wrote a simple little test program to read in some data I typed in at the terminal, and process it. begin Main: loop Put ("Enter: "); Get_Input: loop begin Get (Data); exit Get_Input; exception when End_Error => exit Main; when Data_Error | Constraint_Error => Skip_Line; Put ("Bad data; try again: "); end; end loop Get_Input; <process Data> end loop Main; This is yet another example of the read-test-process loop idiom. Think of the Get_Input loop as a state: you leave the state when you have good data (and then go process it), or you leave the state (and the outer, Main state too) because you're done with your testing (by pressing CNTL-D on UNIX or CNTL-Z on VMS). You stay in the Get_Input state as long as the user enters bad data (wrong type or out-of-range). Note how the exit statement explicitly identifies the loop to which it applies: either Get_Input or Main. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-15 0:00 ` Matthew Heaney @ 1997-10-16 0:00 ` Joachim Durchholz 1997-10-17 0:00 ` Robert I. Eachus 0 siblings, 1 reply; 132+ messages in thread From: Joachim Durchholz @ 1997-10-16 0:00 UTC (permalink / raw) Fie, what's this! Exceptions used for flow control... Regards, Joachim -- Please don't send unsolicited ads. (The @@ is for confusing spambots.) ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-16 0:00 ` Joachim Durchholz @ 1997-10-17 0:00 ` Robert I. Eachus 0 siblings, 0 replies; 132+ messages in thread From: Robert I. Eachus @ 1997-10-17 0:00 UTC (permalink / raw) In article <34467890.243549EE@munich.netsurf.de> Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes: > Fie, what's this! Exceptions used for flow control... No, a code fragment where errors are explicitly handled. If you examine the code more closely you will notice that the inner loop has an exit statement associated with accepting valid input. You go around that loop again if you have bad input. ONE of the ways to end up rerunning the input loop is if you handle an exception, there are usually several others. This is a common idiom. Now in Ada, it may be right to avoid using exceptions for flow control, but that doesn't mean you should throw the exceptions on the floor or ignore them. And once you handle the error, of course you want to return to the proper state. So any well implemented state machine in Ada will have exception handlers, and even gotos in some of them. But it doesn't mean that that path is expected to be taken outside of testing. -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is... ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-15 0:00 ` Paul Johnson 1997-10-15 0:00 ` Matthew Heaney @ 1997-10-16 0:00 ` Joachim Durchholz 1997-10-22 0:00 ` Reimer Behrends 2 siblings, 0 replies; 132+ messages in thread From: Joachim Durchholz @ 1997-10-16 0:00 UTC (permalink / raw) Paul Johnson wrote: > > I agree that the repeated read (or whatever instruction) before the > loop and at the end is a bad idea. Quite apart from the Soloway > experiment, it is duplicating code. Me too (on both accounts). > OTOH I wonder if the situation might be reversed in real life > situations with deeply nested structures. I'm rather dubious of > small, neat coding experiments such as Soloway's. I can support that from personal experience. Whenever code involved 'break'ing out from several nesting levels deep, it was rather unreadable and difficult to decipher. However, there's a middle ground between "break only at top of loop" and "break everywhere within a loop": "break anywhere at the top level within a loop". A syntax for this might look like this: loop ... until <condition> ... until <condition> ... end loop so one could write loop <read a value> until value = '0' <process value> end loop This avoids both the obfuscation from breaking out from deeply nested code *and* the code duplication necessary if the termination condition is forced to the top of the loop. To satisfy those who are concerned with making sure that the loop does what it has to, and terminates (hi Eiffelists!), the syntax could be set up as follows: <loop> ::= from <loop set-up statements - syntactic sugar> loop <loop statement> <loop statement> ... end <loop statement> ::= [invariant <condition>] -- must be true on every iteration [variant <expression>] -- must decrease on every iteration -- must not decrease beyond a given threshold -- (this ensures that the loop terminates) until <expression> -- termination condition <loop statement> ::= <statement> -- normal statements are allowed, too :) i.e. within the loop body, an arbitrary number of invariant ... variant ... until ... sequences can be placed, with invariant and variant optional. The postcondition of the loop would be the OR of all the invariants ANDed with their respective "until" conditions, so having too many loop exits will make checking and understanding the loop more work, so the number of loop exits should be small. Actually I'm not sure wether such a syntax shouldn't be limited to a single exit - I have very rarely felt the need for mutliple loop exits, and a bit of inconvenience in rare cases is always worth a better language structure. Regards, Joachim -- Please don't send unsolicited ads. (The @@ is for confusing spambots.) ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-15 0:00 ` Paul Johnson 1997-10-15 0:00 ` Matthew Heaney 1997-10-16 0:00 ` Joachim Durchholz @ 1997-10-22 0:00 ` Reimer Behrends 2 siblings, 0 replies; 132+ messages in thread From: Reimer Behrends @ 1997-10-22 0:00 UTC (permalink / raw) Paul Johnson (Paul@treetop.demon.co.uk) wrote: [Discussion of exit-at-top vs. exit-anywhere.] : Hmm. Interesting. : : I agree that the repeated read (or whatever instruction) before the loop : and at the end is a bad idea. Quite apart from the Soloway experiment, : it is duplicating code. Yes, but ... see below. : OTOH I wonder if the situation might be reversed in real life situations : with deeply nested structures. I'm rather dubious of small, neat coding : experiments such as Soloway's. While they are the best handle we have : on the facts, I worry that in an attempt to come up with a controllable, : repeatable, and above all feasible experiment, they abstract out too : much complexity. After all, it is complexity that makes programming : difficult. You have a point here, I think. It is worth noting that the example discussed not only was a toy program, but also had a couple of bugs in it (didn't work for empty or non-numerical input). This may be perfectly acceptable for prototyping, of course, but not for industrial-strength code. The general problem is that if your task cannot be suitably expressed with one control structure, you have basically two options: (1) "Rewire" the control flow. (2) Think of suitable abstractions instead of expressing something directly. The most general approach to (1) is to use goto or one of its watered-down variants (break, continue, Sather style iterators, etc.). The problem with them is that if only you use them often enough you lose the clarity of single-entry, single-exit structures. It becomes hard to understand the code or produce test cases that provide adequate coverage. This is (aside from general gotos) particularly extreme if you have multi-level breaks, breaks inside deeply nested if-statements, etc. It should be noted, however, that just removing such constructs from the syntax of the language doesn't necessarily alleviate the problem. You can always simulate them with boolean variables, and code that makes ample use of this "solution" will probably be even harder to understand. That doesn't mean that you boolean variables shouldn't be used as convenient abbreviations for complex conditions, just not to simulate gotos. Using (2) appears like the cleaner solution, and it probably is. After all, didn't structured programming teach years ago that if we have code that is long, complex, or repeated in more than one place, we should try to encapsulate suitable parts in subroutines? It should be noticed, however, that writing such abstractions can be more work initially (which hopefully pays off due to code reuse and making testing and maintenance easier) and relies on a compiler that is capable of decent automatic inlining of code to ensure suitable efficiency for certain applications. Another point is not only choosing to use abstractions, but also to choose _suitable_ abstractions. For instance, much of the problem in the original example (reading integers and adding them until a zero is encountered, I think) stem from the fact that "read" is not really a good abstraction for complex computations. Like the "x++" operator in C, it lumps two marginally related operations together without a good reason. This becomes much clearer when you try to use it with more advanced parsing methods. For instance, with shift-reduce parsers, you will always have to undo the read operation when doing a reduce. Providing separate primitives for advancing the input stream and checking the current token not only work much better for that case, they are also easier extend if you suddenly need a lookahead > 1. A similar case can be made for handwritten LL(k) parsers. Much of their bad reputation (besides the fact that it _is_ easier and safer to write a parser using a tool) stems from the fact that with the traditional read operations grammar rules don't map as nicely to code as when you have both an advance and a lookahead operation, because the entry into/exit from the code for a rule often does not correspond to the current position of the input stream. I seem to remember that Bertrand Meyer suggested somewhere that a routine should either query the state of an object, or change it, but never both (i.e. function vs. procedure). I think we have a good example here why to avoid the latter approach. Of course, with an appropriate INTEGER_SCANNER class the code is no less clear than the original example: from scanner.start(...) sum := 0 until scanner.stopped or else scanner.data = 0 loop sum := sum + scanner.data scanner.advance end This also takes care of end-of-file and error conditions that can occur. Yes, "start" and "advance" will probably call a common routine. That's only natural, as they both have to ensure the class invariant is right in a similar fashion. And it doesn't duplicate code. [...] Reimer Behrends ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-01 0:00 ` Anonymous 1997-10-01 0:00 ` Paul M Gover @ 1997-10-01 0:00 ` Joachim Durchholz 1997-10-02 0:00 ` Robert A Duff 2 siblings, 0 replies; 132+ messages in thread From: Joachim Durchholz @ 1997-10-01 0:00 UTC (permalink / raw) Anonymous wrote: > > Certainly "while" is preferred by those doing program correctness > proofs; all the techniques for this that I have seen have been for > "while" loops. Avoiding "while" does usually make for more readable > code. In this specific example, "while" requires a flag variable, > which is less readable than using "exit". Actually positive/negative logic has nothing to do with why the correctness guys prefer "while". What they want is that the termination condition is at the start of the loop. Actually Eiffel doesn't use "while", it uses "until". The correct syntax is: from -- loop initialization - arbitrary code invariant -- here goes the loop invariant, a boolean expression that's -- true whenever execution reaches the top of the loop. -- loop invariants are useful to prove the correctness. variant -- here the loop variant - an expression that will decrease -- with every iteration. -- loop variants are useful to prove that the loop will terminate. until -- put your termination condition here loop -- statements to be repeated end The "from" part is just syntactic sugar - leaving away the "from" keyword won't change the semantics. Still it's useful to indicate the beginning of the loop set-up code - it's often rather contrived to force the loop invariant on the first go through the loop. "invariant" and "variant" are the algorithm prover's tools. However, proving and convincing somebody that it actually works is much the same, i.e. these constructs are even useful when hacking. In particular if you're in doubt wether your loop does exactly what it should, and wether it terminates at all! Remember your first attempts at binary search in an array? The above construct has interesting properties (which will be well-known to algorithm provers): 1. If a variant is present the code is guaranteed to terminate. Quite useful for loops. 2. The loop invariant will be true at the start and at the end of the code of the loop body. 3. When the loop terminates, both the invariant and the termination condition will hold. Usually you don't have to look at the loop body to understand what the loop is doing. 4. When reading a loop without the invariant stated, the worst problem for understanding the code is this: We know numerous conditions that are true when execution reaches the top of the loop, but we don't know which of these conditions will be destroyed by the loop body. So we don't understand which conditions will still hold for the second iteration, i.e. we don't know what conditions the code of the loop body assumes. This makes understanding the code extremely difficult - this is much like reading the body of a routine without being allowed to look at the parameter and local variable declarations (actually I think it's worse). Regards, Joachim -- Please don't send unsolicited ads. (The @@ is for confusing spambots.) ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-01 0:00 ` Anonymous 1997-10-01 0:00 ` Paul M Gover 1997-10-01 0:00 ` Joachim Durchholz @ 1997-10-02 0:00 ` Robert A Duff 1997-10-02 0:00 ` Tucker Taft ` (2 more replies) 2 siblings, 3 replies; 132+ messages in thread From: Robert A Duff @ 1997-10-02 0:00 UTC (permalink / raw) In article <199710011402.QAA02444@basement.replay.com>, Anonymous <nobody@REPLAY.COM> wrote: >..."While" was said to be undesireable because it tends >to require the use of negative logic, which is less readable than >positive logic: It requires negative logic in *this* case, because there happens to be an End_Of_File function, rather than (say) a Within_File function. Sure, *some* while loops require negative logic, but some don't: "while X in Some_Subtype loop" vs. "exit when X not in Some_Subtype" "while X <= Max loop" vs "exit when X > Max" "while Is_Good(X) loop" vs "exit when Is_Evil(X)" I always prefer a while loop if there is exactly one exit condition at the start. I think this is usually the case -- I would guess I've written perhaps 10 times as many while loops as loops-with-exit in my life (in Ada, I mean -- other languages sometimes have different features). >Read : while not End_Of_File (Fred) loop > >Read : loop > exit Read when End_Of_File (Fred); > >It was included in the language for the same reason as "goto": to >facilitate automated translation from languages that include the >feature. I find this statement rather dubious. For one thing, I can't believe that Ichbiah et al were that down on while loops. (I can believe they advocated avoiding "not"s, but not all while loops need nots.) For another thing, there's a trivial transformation from "while" to loop-with-exit-at-the-start, so how is this necessary for automated translation? In the goto case, the transformation is not so trivial. >Certainly "while" is preferred by those doing program correctness >proofs; all the techniques for this that I have seen have been for >"while" loops. Avoiding "while" does usually make for more readable >code. In this specific example, "while" requires a flag variable, which >is less readable than using "exit". I certainly agree that using an "exit" is better than having extra flags and whatnot. But I think this is the less common case -- in the most common case, "while" does just fine. I certainly don't believe that "while considered harmful"! I'm also a bit suspicious of "program correctness proof" arguments, if the argument pushes toward writing less readable code (or lots more code). In such cases, it seems like the proof techniques are lacking, not the code one is trying to prove something about. (E.g. if somebody says (and they have), don't use generics, because they're hard to prove correct, and that means I have to write 17 different Stack packages, instead of one generic one, I blame the proof techniques, not the generic.) >...For this reason, "exit" and the possiblity of multiple >exits were included in Ada, and are considered acceptable by all >competent software engineers. OK, then I'll claim that "while" is considered acceptable by all competent software engineers. ;-) Is this a statement about what the authorities say, or is it a definition of who's competent and who isn't? ;-) By the way, speaking of negative logic, what do people think about negative logic in "if" statements? I tend to try to reduce the number of "not"s in the code. But other people tend to use some other heuristic, such as "do the normal case first" or "do unusual case first". For example: if Is_Evil(X) then print error message; else ... -- 37 lines of code doing the normal thing end if; vs if not Is_Evil(X) then ... -- 37 lines of code doing the normal thing else print error message; end if; vs if Is_Good(X) then ... -- 37 lines of code doing the normal thing else print error message; end if; vs if not Is_Good(X) then print error message; else ... -- 37 lines of code doing the normal thing end if; Or perhaps even: if Is_Evil(X) then print error message; return; end if; ... -- 37 lines of code doing the normal thing - Bob ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-02 0:00 ` Robert A Duff @ 1997-10-02 0:00 ` Tucker Taft 1997-10-02 0:00 ` Matthew Heaney 1997-10-03 0:00 ` Stephen Leake 1997-10-04 0:00 ` Matthew Heaney 2 siblings, 1 reply; 132+ messages in thread From: Tucker Taft @ 1997-10-02 0:00 UTC (permalink / raw) Robert A Duff (bobduff@world.std.com) wrote: : ... : By the way, speaking of negative logic, what do people think about : negative logic in "if" statements? I tend to try to reduce the number : of "not"s in the code. But other people tend to use some other : heuristic, such as "do the normal case first" or "do unusual case : first". FWIW, one of my heuristics is if one case is much shorter than the other, do the shorter case first, as it is easier to see what is happening. When you see something like: ... 200 lines else Do_Something; end if; you can pretty easily lose track of what was the original condition being tested. Of course, another solution is to put a nice comment after the "else" to say what is the condition governing the second case. However, even if you put a comment on the else, I still find it clearer to finish off the short case first, and then do the complicated one. : - Bob -- -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Burlington, MA USA ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-02 0:00 ` Tucker Taft @ 1997-10-02 0:00 ` Matthew Heaney 0 siblings, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-10-02 0:00 UTC (permalink / raw) In article <EHG0o5.K03.0.-s@inmet.camb.inmet.com>, stt@houdini.camb.inmet.com (Tucker Taft) wrote: >Robert A Duff (bobduff@world.std.com) wrote: > >: ... >: By the way, speaking of negative logic, what do people think about >: negative logic in "if" statements? I tend to try to reduce the number >: of "not"s in the code. But other people tend to use some other >: heuristic, such as "do the normal case first" or "do unusual case >: first". > >FWIW, one of my heuristics is if one case is much shorter than the other, >do the shorter case first, as it is easier to see what is happening. >When you see something like: > > ... 200 lines > else > Do_Something; > end if; That about sums it up for me too. I like to handle the special cases right up in front. That often means checking preconditions that aren't expressable in Ada syntax (hint, hint). I would have implemented Tuck's example as if not P then Do_Something; return; end if; ...200 lines One of the benefits of this approach is that it removes a level of nesting. A simple example of a precondition check is a stack pop. Instead of procedure Pop (Stack : in out Bounded_Stack) is begin if Stack.Top /= 0 then Stack.Top := Stack.Top - 1; else raise Stack_Empty; end if; end; I would do this as procedure Pop (Stack : in out Bounded_Stack) is begin if Stack.Top = 0 then raise Stack_Empty; end if; Stack.Top := Stack.Top - 1; end; This is what I meant by "check preconditions at top of subprogram." Get the special cases out of the way. Of course, you can also let Ada do the check for you. If the Top component is of type Natural, then procedure Pop (Stack : in out Bounded_Stack) is begin Stack.Top := Stack.Top - 1; exception when Constraint_Error => raise Stack_Empty; end; You have to be careful with this style, though; do too much in the exception handler and you can get burned by RM 11.6 subtleties. Of course, it would be really cool if I could declare Pop as procedure Pop (Stack : in out Root_Stack) precondition Not_Empty: Length (Stack) > 0; end Pop; and then Ada could check the precondition for me. David Luckham wrote a paper (and a whole annotation language) describing exception annotations, something like: procedure Pop (Stack : in out Root_Stack) exception when Length (Stack) = 0 => raise Stack_Empty; end Pop; Maybe we can look into this for the next language update, hmmmm? -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-02 0:00 ` Robert A Duff 1997-10-02 0:00 ` Tucker Taft @ 1997-10-03 0:00 ` Stephen Leake 1997-10-04 0:00 ` Matthew Heaney 2 siblings, 0 replies; 132+ messages in thread From: Stephen Leake @ 1997-10-03 0:00 UTC (permalink / raw) Robert A Duff wrote: > By the way, speaking of negative logic, what do people think about > negative logic in "if" statements? I tend to try to reduce the number > of "not"s in the code. But other people tend to use some other > heuristic, such as "do the normal case first" or "do unusual case > first". For example: > > if Is_Evil(X) then > print error message; > else > ... -- 37 lines of code doing the normal thing > end if; I prefer this style; put the easily handled case first. > > vs > > if not Is_Evil(X) then > ... -- 37 lines of code doing the normal thing > else > print error message; > end if; > > vs > > if Is_Good(X) then > ... -- 37 lines of code doing the normal thing > else > print error message; > end if; > > vs > > if not Is_Good(X) then > print error message; > else > ... -- 37 lines of code doing the normal thing > end if; > > Or perhaps even: > > if Is_Evil(X) then > print error message; > return; > end if; > ... -- 37 lines of code doing the normal thing I also do this, especially when the 'return' gets me out of more than one layer of 'if' > > - Bob -- - Stephe ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-02 0:00 ` Robert A Duff 1997-10-02 0:00 ` Tucker Taft 1997-10-03 0:00 ` Stephen Leake @ 1997-10-04 0:00 ` Matthew Heaney 1997-10-07 0:00 ` Robert A Duff 2 siblings, 1 reply; 132+ messages in thread From: Matthew Heaney @ 1997-10-04 0:00 UTC (permalink / raw) In article <EHFvt5.D1G@world.std.com>, bobduff@world.std.com (Robert A Duff) wrote: >By the way, speaking of negative logic, what do people think about >negative logic in "if" statements? I tend to try to reduce the number >of "not"s in the code. But other people tend to use some other >heuristic, such as "do the normal case first" or "do unusual case >first". For example: I like to handle the exceptional case first, and return early. >Or perhaps even: > > if Is_Evil(X) then > print error message; > return; > end if; > ... -- 37 lines of code doing the normal thing This one gets my vote. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-10-04 0:00 ` Matthew Heaney @ 1997-10-07 0:00 ` Robert A Duff 0 siblings, 0 replies; 132+ messages in thread From: Robert A Duff @ 1997-10-07 0:00 UTC (permalink / raw) In article <mheaney-ya023680000410971755550001@news.ni.net>, Matthew Heaney <mheaney@ni.net> wrote: >I like to handle the exceptional case first, and return early. > >>Or perhaps even: >> >> if Is_Evil(X) then >> print error message; >> return; >> end if; >> ... -- 37 lines of code doing the normal thing > >This one gets my vote. Yeah, I often do that sort of thing, too. But I've been burned more than once by return_statements in this way: I want to add some code that gets executed just before the procedure leaves, and I add it at the end without noticing that there's a return_statement buried somewhere near the beginning (perhaps a couple of nesting-levels deep). In *that* regard, a goto is better than a return, because you can add code just after the label. - Bob ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-20 0:00 ` Joachim Durchholz ` (2 preceding siblings ...) 1997-09-24 0:00 ` Alan E & Carmel J Brain @ 1997-09-24 0:00 ` Richard A. O'Keefe 3 siblings, 0 replies; 132+ messages in thread From: Richard A. O'Keefe @ 1997-09-24 0:00 UTC (permalink / raw) Joachim Durchholz <joachim.durchholz@munich.netsurf.de> writes: >I don't like the Ada solution either. It is "structured" in that it will >resume execution at the point where the execution occurred, but that's >*very* wrong. The exception handler can't know at which point in the >code the exception occurred (maybe even in a subroutine!), so it can't >know what to do to fix the problem. Are we talking about the same language? Ada exceptions are 'termination' exceptions. PL/I has exception resumption. Common Lisp has exception resumption. Ada does not. One thing an Ada exception handler _can't_ do is "resume execution at the point where the exception" was raised. -- Unsolicited commercial E-mail to this account is prohibited; see section 76E of the Commonwealth Crimes Act 1914 as amended by the Crimes Legislation Amendment Act No 108 of 1989. Maximum penalty: 10 years in gaol. Richard A. O'Keefe; http://www.cs.rmit.edu.au/%7Eok; RMIT Comp.Sci. ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-18 0:00 ` Stephen Leake 1997-09-18 0:00 ` Mark L. Fussell @ 1997-09-18 0:00 ` W. Wesley Groleau x4923 1997-09-21 0:00 ` Matthew Heaney 1 sibling, 1 reply; 132+ messages in thread From: W. Wesley Groleau x4923 @ 1997-09-18 0:00 UTC (permalink / raw) Stephen Leake wrote: > > Paul Johnson wrote: > > > > Ada allows the programmer to quietly ignore an exception and pretend > > that a routine succeeded when in fact it failed. This is wrong. > > I assume you are talking about: > begin > ... some code > exception > when others => > null; > end; > > which ignores exceptions. Usually, this is a bad idea. But sometimes, it > is essential. Consider the top level loop of a fail-safe system: Or, perhaps I know that the guy that wrote routine X sometimes raises exception Y AFTER X has already done the work I want. Why shouldn't I ignore exception Y in that case? > This is a general philosophy of Ada; provide the tools to do various > jobs. Don't force a programmer to do something because it's "good". Uh-oh. That sounds like an argument for a fan of C (Also sounds like the argument against forcing declaration before reference.) -- ---------------------------------------------------------------------- Wes Groleau, Hughes Defense Communications, Fort Wayne, IN USA Senior Software Engineer - AFATDS Tool-smith Wanna-be wwgrol AT pseserv3.fw.hac.com Don't send advertisements to this domain unless asked! All disk space on fw.hac.com hosts belongs to either Hughes Defense Communications or the United States government. Using email to store YOUR advertising on them is trespassing! ---------------------------------------------------------------------- ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract) 1997-09-18 0:00 ` W. Wesley Groleau x4923 @ 1997-09-21 0:00 ` Matthew Heaney 0 siblings, 0 replies; 132+ messages in thread From: Matthew Heaney @ 1997-09-21 0:00 UTC (permalink / raw) In article <3421A76F.4709@pseserv3.fw.hac.com>, "W. Wesley Groleau x4923" <wwgrol@pseserv3.fw.hac.com> wrote: >Or, perhaps I know that the guy that wrote routine X sometimes >raises exception Y AFTER X has already done the work I want. >Why shouldn't I ignore exception Y in that case? This is a misuse of the exception mechanism. Either the subprogram does the work, satisfying the postcondition, or raises an exception, because it cannot satisfy its postcondition. Don't use exceptions as a way of passing back status in the normal case, use them strictly to indicate failure to satisfy postconditions. (And also to indicate failure by the client to satisfy preconditions.) -------------------------------------------------------------------- Matthew Heaney Software Development Consultant <mailto:matthew_heaney@acm.org> (818) 985-1271 ^ permalink raw reply [flat|nested] 132+ messages in thread
* Re: Building blocks (Was: Design By Contract)
@ 1997-09-11 0:00 Robert Dewar
0 siblings, 0 replies; 132+ messages in thread
From: Robert Dewar @ 1997-09-11 0:00 UTC (permalink / raw)
Brian Rogoff complained, quite rightly, to me as quoted below. Sorry for
the mistake in attributions, it is often easy to get confused, and especially
to borrow confusion. Too bad this is not all automated :-)
--
Brian's msg:
Please be careful with attributions, I never wrote that, that was Paul
Johnson! I wrote a rebuttal that Matthew Heaney carelessly edited in his
own follow-up.
-- Brian
On 10 Sep 1997, Robert Dewar wrote:
> Brian Rogoff said
>
> <<>>In fact the Eiffel exception mechanism is superior to the Ada one
> >> because it is built on a theoretical model of software engineering.>>
>
> This is one of the more absurd statements in what is unfortunately becoming
> a rather tedious thread. First of all, the idea that being "built on
> *a* (i.e. any old) theoretical model of software engineering" is per se
> a good thing is a bit laughable.
>
> Second, of course the Ada exception mechanism is build on such a model
> also -- indeed it *is* a model itself!
>
> Rather thank make vague religeous statements like this which have
> zero meaning, say EXACTLY what technical point you are trying to make.
^ permalink raw reply [flat|nested] 132+ messages in thread
end of thread, other threads:[~1997-10-22 0:00 UTC | newest] Thread overview: 132+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1997-08-21 0:00 Critique of Ariane 5 paper (finally!) aek [not found] ` <33FC66AD.9A0799D4@calfp.co.uk> 1997-08-22 0:00 ` Robert S. White 1997-08-22 0:00 ` Samuel Mize 1997-08-22 0:00 ` Samuel Mize 1997-08-23 0:00 ` Ken Garlington [not found] ` <33FFA4B1.3543@flash.net> 1997-08-26 0:00 ` Nick Leaton [not found] ` <3403940F.4154@pseserv3.fw.hac.com> 1997-08-27 0:00 ` Design By Contract Ted Velkoff [not found] ` <5u3c6v$gtf$2@miranda.gmrc.gecm.com> 1997-08-28 0:00 ` Patrick Doyle 1997-09-06 0:00 ` Joachim Durchholz 1997-09-06 0:00 ` Patrick Doyle [not found] ` <34058808.3BF@pseserv3.fw.hac.com> 1997-08-28 0:00 ` Darren New [not found] ` <JSA.97Aug27180328@alexandria.organon.com> 1997-08-28 0:00 ` W. Wesley Groleau x4923 1997-09-03 0:00 ` Don Harrison 1997-09-03 0:00 ` Jon S Anthony 1997-09-04 0:00 ` Don Harrison [not found] ` <EFM140.Fy9@syd.csa.com.au> 1997-08-28 0:00 ` Jon S Anthony 1997-08-29 0:00 ` Patrick Doyle 1997-08-29 0:00 ` Jon S Anthony [not found] ` <EFqDw0.3x7@ecf.toronto.edu> [not found] ` <JSA.97Aug30145354@alexandria.organon.com> 1997-09-01 0:00 ` Patrick Doyle 1997-08-29 0:00 ` Don Harrison 1997-08-29 0:00 ` Jon S Anthony [not found] ` <EFqE8L.4Eq@ecf.toronto.edu> [not found] ` <JSA.97Aug30145058@alexandria.organon.com> 1997-09-01 0:00 ` Patrick Doyle 1997-09-02 0:00 ` Don Harrison 1997-09-02 0:00 ` Jon S Anthony 1997-09-03 0:00 ` Don Harrison [not found] ` <JSA.97Sep3201329@alexandria.organon.com> 1997-09-04 0:00 ` Paul Johnson 1997-09-05 0:00 ` Jon S Anthony 1997-09-08 0:00 ` Nick Leaton 1997-09-08 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Paul Johnson [not found] ` <5un58u$9ih$1@gonzo.sun3.iaf.nl> 1997-09-06 0:00 ` Building blocks (Was: Design By Contract) Joachim Durchholz 1997-09-08 0:00 ` Paul Johnson 1997-09-08 0:00 ` Brian Rogoff 1997-09-09 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Brian Rogoff 1997-09-09 0:00 ` W. Wesley Groleau x4923 1997-09-10 0:00 ` Robert A Duff 1997-09-12 0:00 ` Jon S Anthony 1997-09-10 0:00 ` Paul Johnson 1997-09-10 0:00 ` Matthew Heaney 1997-09-10 0:00 ` Darren New 1997-09-10 0:00 ` Robert Dewar 1997-09-12 0:00 ` Paul Johnson 1997-09-14 0:00 ` Robert Dewar 1997-09-15 0:00 ` John G. Volan 1997-09-14 0:00 ` Robert Dewar 1997-09-14 0:00 ` Robert Dewar 1997-09-12 0:00 ` Jon S Anthony 1997-09-12 0:00 ` Robert Dewar 1997-09-16 0:00 ` Brian Rogoff 1997-09-09 0:00 ` W. Wesley Groleau x4923 1997-09-09 0:00 ` Veli-Pekka Nousiainen 1997-09-09 0:00 ` Veli-Pekka Nousiainen 1997-09-09 0:00 ` Jon S Anthony [not found] ` <EFzLn7.481@ecf.toronto.edu> 1997-09-04 0:00 ` Design By Contract Jon S Anthony [not found] ` <EFz0pD.E6n@syd.csa.com.au> 1997-09-05 0:00 ` W. Wesley Groleau x4923 1997-09-05 0:00 ` subjectivity W. Wesley Groleau x4923 1997-09-05 0:00 ` subjectivity Matthew Heaney 1997-09-10 0:00 ` subjectivity Don Harrison 1997-09-12 0:00 ` subjectivity Jon S Anthony 1997-09-16 0:00 ` subjectivity Don Harrison 1997-09-16 0:00 ` subjectivity Jon S Anthony 1997-09-10 0:00 ` subjectivity Don Harrison 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 1997-09-11 0:00 ` subjectivity Don Harrison 1997-09-10 0:00 ` subjectivity W. Wesley Groleau x4923 [not found] ` <JSA.97Sep4172912@alexandria.organon.com> [not found] ` <EG0oz8.F6M@syd.csa.com.au> 1997-09-05 0:00 ` Design By Contract Jon S Anthony 1997-09-05 0:00 ` Nick Leaton 1997-09-08 0:00 ` Jon S Anthony 1997-09-09 0:00 ` Nick Leaton 1997-09-10 0:00 ` Paul Johnson 1997-09-06 0:00 ` Patrick Doyle [not found] ` <EG0rp7.GtL@syd.csa.com.au> 1997-09-05 0:00 ` Matthew Heaney 1997-09-09 0:00 ` Robert A Duff 1997-09-09 0:00 ` Matthew Heaney 1997-09-02 0:00 ` Joerg Rodemann 1997-09-02 0:00 ` Jon S Anthony 1997-08-28 0:00 ` Robert Dewar 1997-08-29 0:00 ` Don Harrison [not found] ` <349224633wnr@eiffel.demon.co.uk> 1997-08-27 0:00 ` Design by Contract Robert Dewar 1997-08-29 0:00 ` Don Harrison [not found] ` <3406BEF7.2FC3@flash.net> [not found] ` <3406E0F7.6FF7ED99@calfp.co.uk> 1997-09-02 0:00 ` Critique of Ariane 5 paper (finally!) Ken Garlington -- strict thread matches above, loose matches on Subject: below -- 1997-09-09 0:00 Building blocks (Was: Design By Contract) Marc Wachowitz 1997-09-09 0:00 Marc Wachowitz 1997-09-15 0:00 ` Joachim Durchholz 1997-09-17 0:00 ` Paul Johnson 1997-09-18 0:00 ` Robert Dewar 1997-09-18 0:00 ` Jon S Anthony 1997-09-18 0:00 ` Stephen Leake 1997-09-18 0:00 ` Mark L. Fussell [not found] ` <11861963wnr@eiffel.demon.co.uk> 1997-09-19 0:00 ` Mark L. Fussell 1997-09-19 0:00 ` Jon S Anthony 1997-09-23 0:00 ` Mark L. Fussell 1997-09-19 0:00 ` Robert A Duff 1997-09-20 0:00 ` Joachim Durchholz 1997-09-22 0:00 ` Matthew Heaney 1997-09-23 0:00 ` Veli-Pekka Nousiainen 1997-10-03 0:00 ` Robert I. Eachus 1997-10-04 0:00 ` Paul Johnson 1997-10-14 0:00 ` Robert I. Eachus 1997-09-23 0:00 ` Joachim Durchholz 1997-09-23 0:00 ` Jon S Anthony 1997-09-24 0:00 ` Alan E & Carmel J Brain 1997-09-25 0:00 ` Anonymous 1997-09-30 0:00 ` Alan E & Carmel J Brain 1997-09-30 0:00 ` Matthew Heaney 1997-09-30 0:00 ` Neil Wilson 1997-09-30 0:00 ` Stephen Leake 1997-09-30 0:00 ` W. Wesley Groleau x4923 1997-09-30 0:00 ` Matthew Heaney 1997-10-01 0:00 ` Alan E & Carmel J Brain 1997-10-01 0:00 ` Anonymous 1997-10-01 0:00 ` Paul M Gover 1997-10-04 0:00 ` Paul Johnson 1997-10-04 0:00 ` Matthew Heaney 1997-10-15 0:00 ` Paul Johnson 1997-10-15 0:00 ` Matthew Heaney 1997-10-16 0:00 ` Joachim Durchholz 1997-10-17 0:00 ` Robert I. Eachus 1997-10-16 0:00 ` Joachim Durchholz 1997-10-22 0:00 ` Reimer Behrends 1997-10-01 0:00 ` Joachim Durchholz 1997-10-02 0:00 ` Robert A Duff 1997-10-02 0:00 ` Tucker Taft 1997-10-02 0:00 ` Matthew Heaney 1997-10-03 0:00 ` Stephen Leake 1997-10-04 0:00 ` Matthew Heaney 1997-10-07 0:00 ` Robert A Duff 1997-09-24 0:00 ` Richard A. O'Keefe 1997-09-18 0:00 ` W. Wesley Groleau x4923 1997-09-21 0:00 ` Matthew Heaney 1997-09-11 0:00 Robert Dewar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox