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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no 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: donh@syd.csa.com.au (Don Harrison) Subject: Re: Real OO Date: 1996/04/12 Message-ID: X-Deja-AN: 147074142 sender: news@assip.csasyd.oz references: organization: CSC Australia reply-to: donh@syd.csa.com.au newsgroups: comp.lang.eiffel,comp.lang.ada,comp.object Date: 1996-04-12T00:00:00+00:00 List-Id: Jon S Anthony writes: :In article donh@syd.csa.com.au (Don Harrison) writes: [...] :> Apart from the efficiency aspect, I wonder is the eagerness of Ada :> programmers to freeze routines related to the fact that assertions :> aren't available to: - guard against errors in parents being :> propagated into descendant classes, and - correctness in parents :> being compromised in descendants? ;-) : :I think you are confused here. Don't start thinking that Eiffel's :"frozen" feature is the equivalent of a classwide operation. It is :not. Classwide operations are more general and flexible and cover :other sorts of ground beyond what you have with simple frozen features. Yes, Eiffel's frozen routines alone are not the equivalent of Ada's classwide operations. The Eiffel analogue is a combination of: a) frozen routines, which make a routine classwide for Current, and b) parameters, all of which are classwide by default, and c) results of functions, which are classwide by default. This provides the same generality and flexibility of Ada's classwide operations. Note that it is really meaningless to speak of 'classwide operations' but rather of classwide entities because a routine may be dispatching wrt one parameter (Current) but is classwide wrt the parameters and the result (if any). The following table shows some equivalent operations in Eiffel and Ada. They are dispatching wrt some parameters and classwide wrt others (eg. 2. below). Ada Eiffel ------------------------------------------------------------------------------------ Assuming type T is private; -- tagged class T ... end type U is private; -- tagged class U ... end ------------------------------------------------------------------------------------ (in class T) (in class U) 1. procedure f (a: T'Class) frozen f 2. procedure g (a: T; b: U'Class) g (b: U) 3. procedure h (a: T'Class; b: U'Class) frozen h (b: U) frozen h (a: T) 4. function i (a: T'Class) return T'Class frozen i: like Current 5. function j (b: U'Class) return T'Class frozen j : T [...] :Well, now that is odd as Joachim disputes your claim and sites an :ETL reference that it is indeed _dynamic_. If he did, then I missed it. :> :It's the "or a type that is a descendant of" that differentiates the :> :Eiffel approach from the Ada approach. :> :> ... and makes the Eiffel approach more flexible (and robust: Ada raises a :> Constraint_Error exception if the dynamic types of multiple controlling :> operands differ RM95 3.9.2 (16) ). : :Not if you are using classwide types and operations. You can't even :_have_ multiple controlling parameters in Eiffel so it is certainly no :more "flexible" here. Nor would we want to. One operand, Current, is more than adequate to convey the information in accordance with the OO principle of uniqueness. In Ada, with the second, third, fourth, ... and nth operands of the same specific type controlling dispatching, by the time the compiler gets to the end of the routine signature, it is rolling it's eyes and crying: "Good grief, I heard you the first time!!!" : And what's more, there are several cases where :Eiffel either a) ensures dynamic type integrity with runtime errors or :b) tries to determine this with the infamous system validity check. :(which many (most??) implementations do not even try to do. Yes, I :know there is/was some attempt to remove this, but the impression is :it is still a problem). You are referring to catcalls: calls which fail because a descendant class makes changes which render the call non-polymorphic wrt ancestors. The changes may be: a) a type has been redefined to a non-conformant type, or b) a routine has been made inaccessible due to a change in it's export status. At first sight, it seems silly to permit such things if they can cause problems with polymorphism but there is a worthy motivation for providing such flexibility: allowing reuse of legacy code that does not exactly fit your requirements. I suspect it's only a problem in Eiffel because other languages don't provide that flexibility. Obviously, if Eiffel were more restrictive, it would not be a problem. But flexibility and reuse are regarded as paramount, so the issue arises. It's an acknowledged problem which is currently being addressed but I don't know how. Hopefully, the solution will retain flexibility and efficiently prevent such calls being made. :/Jon :-- :Jon Anthony :Organon Motives, Inc. :1 Williston Road, Suite 4 :Belmont, MA 02178 : :617.484.3383 :jsa@organon.com Don.