Path: utzoo!attcan!uunet!mcsun!ukc!edcastle!lfcs!db From: db@lfcs.ed.ac.uk (Dave Berry) Newsgroups: comp.lang.eiffel Subject: Re: Preconditions and Multiple Inheritance Message-ID: <2964@castle.ed.ac.uk> Date: 21 Mar 90 13:49:55 GMT Reply-To: db@lfcs.ed.ac.uk (Dave Berry) Organization: Laboratory for the Foundations of Computer Science, Edinburgh U Lines: 84 I'm posting this for Andreas Schramm (schramm%uucp.gmdtub@de.uni-dortmund.informatik.unido) because posting to Usenet is not implemented at his site. Dave Berry. ----------------------------------------------------------------------------- > ... Certainly the current situation, where > one sort of precondition (argument types) is covariant and the other > ("require" clause) is contravariant, seems inconsistent. > > Comments? According to Dr. Meyer, covariant redefinition of routine argument types is an indispensable feature. However, if routine argument types are seen as preconditions, their covariant redefinition violates the "programming as contracting" paradigm, which requires that preconditions must not be strengthened (contravariance). In order to reconcile the two conflicting requirements I propose: Make the extent to which argument type redefinitions in descendant classes are permitted part of the contract. Enforce that routine redefinitions are bound by the contract as it has been defined by the original top-most supplier of a routine. This appears tolerable since the original supplier should usually know in advance which argument type restrictions will make sense when subtypes are introduced. This assumption is justified because the original definition is supposed to fix the meaning of a routine and all its redefinitions, while redefinitions are supposed to be just specialized implementations [OOSC 10.1.10]. Note that it has never been a requirement that contracts are phrased in statically checkable terms. In fact, preconditions (which are part of a contract) often are not. Thus an appropriately phrased contract may e.g. tie routine argument types to the state space of the object involved, which amounts to covariant argument type redefinitions. Some time ago I wrote a letter to Dr. Meyer which contained a suggestion how to to embed this idea in Eiffel. The suggestion was: The top-most definition of a routine fixes its argument types _textually_ once and for all, i.e. for redefinitions the argument types have to be copied textually. The necessary flexibility is preserved because an argument type need not necessarily be a class type but may be of the form "like a" or may refer to a formal generic type parameter. This, by the way, requires the following modification of the rule above: Anchor renamings and instantiations of the parents' formal generic type parameters at inheritance time have to be taken into account. An argument declaration "x: A" would mean that the contract includes "Every redefinition shall accept an argument of type A". An argument declaration "x: like a" would mean that the contract includes "Every redefinition shall accept an argument of a dynamic type that conforms to the declared type of feature a in the class of the type of the object involved at run-time." The former phrase is static, the latter dynamic in nature. In order to imitate the original flexibility of argument type redefinitions, at worst an artificial anchor might have to be introduced; but it strikes me that covariant argument type redefinitions often refer to an already existing feature anyway. Andreas Schramm Dave Berry, LFCS, Edinburgh Uni. db%lfcs.ed.ac.uk@nsfnet-relay.ac.uk "Excuse me, Mr. Policeman, but someone seems to have stolen my soul. What're you going to do about that then, Officer?" -- Here and Now.