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: jsa@organon.com (Jon S Anthony) Subject: Re: Real OO Date: 1996/04/19 Message-ID: X-Deja-AN: 150395802 sender: news@organon.com (news) references: organization: Organon Motives, Inc. newsgroups: comp.lang.eiffel,comp.lang.ada,comp.object Date: 1996-04-19T00:00:00+00:00 List-Id: In article donh@syd.csa.com.au (Don Harrison) writes: > :> 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. > : > :I don't see how. > > I think the examples which I listed speak for themselves. Do you dispute that No, here I'm talking about the points I made in this paragraph, not the table stuff you gave. > : For one thing clients can't define such things > :without introducing gratuitous/extraneous classes (I would say this is > :one of the more important uses). > > Not sure what you mean here. Classes T and U are not extraneous and no more > classes need to be defined. Simply this: Classwide operations can be defined anywhere by anyone. They do not have to be defined along with the primitive types in their packages. So, suppose I have my T and U types (and classes) as you gave in your table. Long after the types/classes have been defined I am writing a client and decide that I need a new operation which is general to these types and a new one that I've just defined, S. It has signature, procedure Op (a: T'Class; b,c: U'Class; d: S'Class); In Ada, I can define this in my specific application as I see fit. Now, in Eiffel you need something like, in Class T in U in S frozen Op ( frozen Op( frozen Op( b:U,c:U,d:S) a:T,c:U,d:S) a:T,c:U,b:U) But this would mean changing the class definitions for all three classes. Even with some clairvoyance you'd have trouble as you couldn't know about S when T and U were defined. So, one possible out would be to subclass them all and put the new frozen features in these new "extraneous" classes and use them instead. > : For another, you need some > :clairvoyance when designing a class in determining the set of features > :to freeze in order to use them in these sorts of combinations > :elsewhere. > > This is no different from Ada. See the discussion above for why this is not true. > :> equivalent operations in Eiffel and Ada. They are dispatching wrt > :> some parameters and classwide wrt others (eg. 2. below). > :>... >... > :Actually, this is a little fuzzy, since there is some other talk in > :ETL where I think you could read Like Current as allowing for anything > :_conformant_ to the type of the object on which the invocation has > :been made. Anyone know the real scoop?? > > If I understand Jacob correctly, the anchored entity conforms both statically > and dynamically to Current. On that basis, I would say that all the examples > I gave are equivalent. I saw his post too and it did seem to confirm that the semantics do mean _conformant_. So, I agree they seem to be functionally equivalent. > [dispatching syntax stuff again] > I'm not about to lose sleep if you disagree. Check. > I guess the Eiffel equivalent to > Ada's multiple controlling operands is something like (assuming the same > definitions): > > function k (a: T; b: T) return T is k (b: like Current): like Current is > begin require > ... Current.conforms_to (b) > end do > ... > ensure > Current.conforms_to (Result) > end > > A little more long-winded but notice the semantics is probably really closer > to what you want because the test on the dynamic type of Result is made after > the routine body: it's nonsense to make assertions about the Result until it This is true in the Ada case as well. The body is statically checked to ensure that the result is T, of course, but during a runtime dispatch the actual result is checked to ensure its dynamic type conforms to its context. So, Ada loses nothing here. > I hope you will agree by now that Eiffel and Ada are as flexible as each other > in terms of the mechanisms they offer. I'm not sure about that. Maybe part of the issue is that "flexible" is not the appropriate term for this discussion... >...[multiple controlling params again...] > Mostly facetious. But I do find it slightly ridiculous to say that there are > multiple controlling operands if it only works if they happen to have the same > dynamic type. I wouldn't say ridiculous as there are some nice aspects you get even at this level. How about, less flexible ;-) > (No, I'm not saying that it should be possible for them to be > different). Actually, I'm not so sure about this. I understand why this limitation was made, but certainly CLOS and Dylan folk would say this _should_ be possible. And they have a point too. > The fact that you get an exception if the types differ is not as > plain as in the Eiffel paradigm, IMO. OK, but I don't see this. > You are referring to catcalls: calls which fail because a descendant class The important point is that these can't be checked at compile time (well, at least not in Eiffel 3), but that the rules require the checks be made _before_ accepting the _system_ for execution. When I say less flexible here, I just mean that _less_ cases can get through to runtime. This _can_ be a _good_ thing. >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 don't quite follow this. It does not seem to have much of anything to do with the problem of system validity checks. I suppose you can claim that overiding export policies and making covariant routine signatures (I think you mean conforming, not non-conforming) is necessary to the emphasized goal, but I don't see it. This goal is trivial to achieve in Ada, do in large part to separation of specifications (interfaces) and implementations (yeah, that old argument). Add to this separation of interface and implementation inheritance, and these problems disappear. > the good reason of allowing reuse of legacy code) and this can cause runtime > errors. If Ada were just as permissive, it would be a problem for Ada too. > In Ada, you can't reuse such code that almost meets your needs; you have to > rewrite it which could be a formidable task. But this is _trivial_ to achieve in Ada without resorting to system validity checks. I don't know why you make such an odd claim. > The intended purpose of system-level validity checks is to identify > and exclude at compile time the stuff that would cause runtime > errors. This is just plain wrong. System validity checks don't happen at compile time, but rather at binding/link time ("long" after the source has been compiled). > for runtime. (Yes, I know that few, if any, Eiffel vendors implement > it). Don't know what you mean here. I mean simply that invalid Eiffel systems are knowingly accepted by these implementations. > : And the reason it is a problem > :is that Eiffel source does not have as much semantic information in it > :in this area. > > What might that be? Specifically, the distinction and use of the difference between class and type. The funny thing is, all this brouhaha about system validity concerns this distinction and an attempt to try to separate them again. Meyer's "dynamic type set" is pretty much an Ada class and his "dynamic class set" is pretty much a class-wide type. > :was a rather good discussion of this stuff about a year ago. Maybe I > :can dig that up. > > Please do. I will try to look it up. If Robb Nebbe is reading, maybe he has a ready and complete "transcript". He was a major participant. /Jon -- Jon Anthony Organon Motives, Inc. 1 Williston Road, Suite 4 Belmont, MA 02178 617.484.3383 jsa@organon.com