From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,c52c30d32b866eae X-Google-Attributes: gidfac41,public X-Google-Thread: 1108a1,c52c30d32b866eae X-Google-Attributes: gid1108a1,public X-Google-Thread: 103376,2ea02452876a15e1 X-Google-Attributes: gid103376,public From: jcm@hgc.edu (James McKim) Subject: Re: Real OO Date: 1996/05/16 Message-ID: <1996May16.151642.20130@merlin.hgc.edu> X-Deja-AN: 155146065 sender: usenet@merlin.hgc.edu (Action News Central) references: organization: The Hartford Graduate Center newsgroups: comp.lang.eiffel,comp.lang.ada,comp.object Date: 1996-05-16T00:00:00+00:00 List-Id: In article donh@syd.csa.com.au writes: >Tucker Taft writes: > >:Don Harrison (donh@syd.csa.com.au) wrote: >:: Tucker Taft writes: >: [..] >: >:The problem is that when you write an assertion, you must >:decide whether you are trying to constrain the current type/class >:as tightly as possible, to catch as many bugs in it as possible, or >:to constrain it as loosely as possible, to allow as much flexibility >:as possible in descendant type/classes. > >Don't think so. I think the objectives of catching bugs and making assertions >about correct behaviour are the same. If you invent an assertion to assist in >debugging, then it should imply a correctness condition. If you invent a >correctness condition, it should also be valuable for debugging. What do >others think? > >IMO, the issue is more one of determining the correct level of abstraction >for an assertion. If it is placed at the correct level, then it will apply >equally well to the current level and for all descendants. No greater >flexibility in descendants should be allowable or needed. I think Don is right in theory, but that Tucker is right in practice. In practice I regularly run into situations in which I want a concrete feature that provides default behavior for descendants, but I don't want the descendants to be totally constrained by that behavior. IOW, I'd like two distinct kinds of assertions. 1. Assertions that bind the current routine and its redefinitions in descendants. 2. Assertions that bind the current routine, but not necessarily its redefinitions in descendants. The latter provide the rigorous specification for the default version of the routine. In Eiffel I try to write the first kind as compilable assertions wherever I can, and use rigorous comments for the second. Of course clients can only depend on the stronger assertions if they're sure no dynamic binding has taken place. > >If a need for greater flexibility is perceived, then you know the design is >incorrect in some way. The solution may be: > >a) Move the assertion lower down the inheritance hierarchy (If this implies > duplicating it in several descendants, then you might consider grouping > the common assertional behaviour by interposing an intermediate level of > abstraction including the common assertion) > >b) Splitting it into a common component and a specific component and moving > the specific component as in a) > There is no one correct design for any sufficiently complex system and in this case, "the perfect is the enemy of the good" (wish I knew who said that). In particular, you cannot redesign any reasonably complex inheritance hierarchy every time you run into this problem because a) You may not have control over all the classes involved. A proprietary library, for example. b) Changing the inheritance hierarchy in such a way may have dramatic and unpleasant repercussions in existing code. c) If you really try for perfection you will end up with separate classes for every _feature_ and _combination_ of features where the problem arises. E.g I need an abstraction where features f and g are loosely specified, one where f is constrained but g is not, one where g is constrained but f is not ... Well, you get the idea. Don't get me wrong, I think we should strive to find useful abstractions that help to relieve the problem. You just don't want to go overboard. [..] > >:It would be reasonable to have both kinds of assertions. As noted above, I agree. Of course this isn't a panacea either, as you still have to predict the appropriate constraints on descendants. There ain't no silver bullet (I know who said that :-)). [..] > >:Another way to look at the problem is whether the assertions >:are focused on the "client" view or the "server" view. >:For a deferred/abstract class, there is no real server, >:so the assertions are clearly client oriented. However >:for a concrete class, the client view and the server view >:are different, and it makes sense to keep the client-oriented >:assertions as weak as possible (but no weaker!), while making >:a specific server's "local" assertions as strong as possible so >:as to catch as many bugs as possible. I agree with the spirit of this, but IMHO you should be thinking at the feature level, not the class level. A deferred class may consist of leventy-leven concrete routines and one deferred routine. I'm not sure the "client/server" distinction holds up here as sometimes the only deferred routines in a class are private ones (I suppose you could say the server is its own client in this case). [..] > > >:-Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ >:Intermetrics, Inc. Cambridge, MA USA > > /// >Don. (o o) >=-=-=-=-=-=-=-=oOO=-(_)-=OOo=-=-=-=-=-=-=-=- >Don Harrison donh@syd.csa.com.au > > Hope this helps, -- Jim -- *------------------------------------------------------------------------------* Jim McKim (860)-548-2458 Co-editor of Eiffel Outlook Internet: jcm@hgc.edu Subscribe early and often!