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: 103376,2ea02452876a15e1 X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: Real OO (was Choice of OO primitives in Ada95) Date: 1996/02/24 Message-ID: X-Deja-AN: 140861920 references: organization: The World Public Access UNIX, Brookline, MA newsgroups: comp.lang.ada Date: 1996-02-24T00:00:00+00:00 List-Id: In article , Don Harrison wrote: >... (I was asking for trouble debating an issue without >the reference material handy). :-) :-) :-) >Note that Ada only fully satisfies 2) and has a sub-optimal mechanism for 1). You've said elsewhere that you don't like Ada's support for 1). I suppose it's something of a matter of taste. I happen to think that Ada's support for 1) is *better* than Eiffel, and the other languages that combine Ada's notion of package and type into one. You seemed to object strongly to the idea that one can put two types in the same package, on the grounds that it decreases encapsulation. On the contrary, it *increases* encapsulation. When two types are closely related to each other, by their nature, *forcing* them to be in separate modules means that *more* operations need to be exported from each module. Encapsulation isn't some sort of Goodness, such that the more you have of it, the better. No, you want to encapsulate things at the "right" level of granularity for the problem at hand. Usually, that's a single type, plus the operations belonging to that type. However, in some cases, two types are so closely related that the right granularity is to put them both in the same package. (After all, in Fortran 66, the only module is the subroutine, which is a *smaller* granularity than the class. But that doesn't make the encapsulation better.) An example is a List type, plus a List_Cursor type. The List_Cursor points at a certain place in the list, and has operations for moving forward and/or backward and so forth. These operations cannot be written without visibility on implementation details of *both* types. So if class=module, you have to *export* a lot of those implemenation details from one of them, so the other one can do what it needs to do. Putting them both in the same module, however, actually gives you *better* encapsulation, because fewer (and higher-level) operations get exported. Last time I looked at Eiffel, the standard library classes put the cursor movement stuff inside the list. That seems like a poor design, since you can only be looping through a given list once, at any given time. It seems to me that you badly want the List_Cursor type to be separate from the List type, although they *are* part of the same "module". >While Eiffel is strong in the OO stakes (it satifies all 3), I agree that Eiffel is superior to Ada with respect to your number 3) -- that is, the assertion stuff. Ada does have *some* support for assertions. For example, if I say, "type T is range 1..10;", then there's an invariant on T -- all objects of type T have to be in the range 1 to 10. This is pretty weak, compared to Eiffel, though. I think it's silly to call that part of OO, though. It's a completely orthogonal issue. Assertions would be useful in a non-OO language, too. If you define "OO" as being "anything I happen to think is good", then the term becomes useless, and people end up arguing about how, "My Daddy is more OO than your Daddy." Meyer also said that garbage collection is a fundamental part of OO. Nonsense. GC existed before OO, and it's not necessary in order to support the real fundamentals of OO, such as polymorphism. Why not just say that GC is a Good Thing, or assertions are a Good Thing, or Eiffel's assertions are better than Ada's assertions, or C++ sucks because it makes it hard to implement GC? It's silly to use the term "OO" as a synonym for "the set of all Good Things". >...it is weak >(unfortunately) in the RT arena. These weaknesses are: > >a) poor low level facilities (bit fiddling) >b) GC renders it an inappropriate tool for hard real-time systems (although the > emergence of mainstream parallel architectures will permit this) Some people believe quite strongly that GC is appropriate for hard real-time systems. But that's another thread. >c) no concurrency (an elegant model currently being implemented - not yet part > of the standard). So I've heard. How does this new elegant model deal with the issue I mentioned above, about putting list-cursor information inside the list itself? If you have multiple tasks, you definitely want to have two tasks iterating through the same shared list (or whatever data structure). Has the standard class library been changed to solve this problem? >I think these will all be addressed in time but if none are a concern to you, >I suggest taking a look at Eiffel. Indeed. Even if they *are* a concern, it's still instructive to learn Eiffel, and to read Meyer's classic book on OOP. Programming by contract is a useful concept in any language. - Bob