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.9 required=5.0 tests=BAYES_00,YOU_INHERIT autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,56dbd715fa74735a X-Google-Attributes: gid103376,public From: John Volan Subject: Re: Mutually dependent private types Date: 1998/05/26 Message-ID: <356B226F.EF05E927@ac3i.dseg.ti.com> X-Deja-AN: 356736704 Content-Transfer-Encoding: 7bit References: <6k25ra$6j7$1@nnrp1.dejanews.com> <3565B105.9BFB4788@ac3i.dseg.ti.com> Content-Type: text/plain; charset=us-ascii Organization: Raytheon Systems Company, Advanced C3I Systems Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 1998-05-26T00:00:00+00:00 List-Id: Matthew Heaney wrote: > > In article <3565B105.9BFB4788@ac3i.dseg.ti.com>, John Volan > wrote: > > >> 3) The mutual dependency in operations is effected by making the other type > >> have type Root'Class, in the spec. In the body, just downcast the object > >> to the representation type. Of course, the compiler can't verify > >> statically that the object is really of the required type, but you'll find > >> out at runtime, because a tag check happens when you downcast. > > > >See http://bluemarble.net/~jvolan/WithingProblem/FAQ.html#strong_typing, > >where I describe how the with-ing problem can be avoided, at the expense > >of Ada95's static strong typing checks, by deriving all your object > >classes from some universal root type (Objects.Object_Type was my > >suggestion). > > Yes, but I don't agree that all tagged types must derive from the _same_ > root type. Each hierarchy can have a different root type. Matt, in your original example, you had T1 and T2 (and T1_Rep and T2_Rep) all derive from a common Root type. That looks a lot like the idea of having a universal root type that everything derives from. (My real objection to your example was that you declared T1_Rep and T2_Rep in a common *package*, which I thought was unnecessary.) But if you want to go in the other direction, sure, you could have these more focused "root" types act as forward declarations for specific "actual" types. Norman Cohen originally came up with that idea: Using inheritance as a mechanism for doing forward type declarations. I still have the same objections to that scheme that I had before: IMHO, Ada95's inheritance was really "intended" to support polymorphic programming, where your problem domain clearly calls for a common generalized abstraction implemented by multiple specialized abstractions. But a forward declaration is the exact *opposite* of polymorphism: A forward type declaration is supposed to bear a one-to-one correspondence with a full type declaration. Simulating a forward type declaration with a spurious extra level of inheritance creates a situation where the compiler thinks you want polymorphism, but you actually don't. As you point out yourself, this spurious polymorphism creates an opportunity where someone could try (either accidentally or maliciously) to provide more than one full type for the same "forward" type. Furthermore, what if you're already using inheritance to support true polymorphism, and then you discover you need to break a mutual dependency somewhere in your class hierarchy? You might end up with a situation I call "inheritance collision": That's where you're trying to apply Ada's inheritance mechanism for two competing purposes, but you're faced with the fact that Ada only supports single inheritance. Sure, it's possible to wiggle your inheritance hierarchy around so that it'll work and you can still keep your mutually-dependent types in different packages. But I find that to be awkward and artificial. Bottom line, I don't think anyone can legitimately claim that Ada95 offers a solution to mutual dependency problems "right out of the box". All you can say is that there are various workarounds, with varying degrees of awkwardness, that can be used to make up for a fundamental hole in the language. [Snip my objection to the loss of strong type checking and the spurious extra tag check...] > There are constraint checks for all additions, subtractions, etc. There > are index checks for array dereferences. There are storage checks during > allocation. etc. One extra tag check isn't going to make a difference I'm not sure you can make an analogy with constraint, index, and storage checks. In general, you can't know statically when an arithmetic operation is going to violate a constraint, or when you're going to run out of memory, and so on, so all of those dynamic checks are necessary. But you can certainly know statically what strong types you're expecting in your variables and subprogram parameters. Type-checking should only become a dynamic thing when you deliberately set up an inheritance hierarchy and do polymorphic class-wide programming. But a simple case of mutual dependency shouldn't call for polymorphism. > Furthermore, this split is only required when there's mutual dependency. > Most types are definately not mutually dependent, and so this workaround > should only seldom be necessary. Depends on the style of software design you're using, which depends a lot on your programming culture. Java, for instance, doesn't place any impediments on mutual dependencies, so there are several cases of mutual dependencies already in the standard Java API. My understanding is that this has caused problems for folks trying to use Ada95 as a front-end language for the Java Virtual Machine. I haven't done much with Ada95-to-JVM compilers (like AdaMagic), so I don't know what solutions they've come up with for that. Maybe Tucker can comment... -- Signature volanSignature = new Signature ( /*name: */ "John G. Volan", /*employer: */ "Raytheon Advanced C3I Systems, San Jose", /*workEmail: */ "johnv@ac3i.dseg.ti.com", /*homeEmail: */ "johnvolan@sprintmail.com", /*selfPlug: */ "Sun Certified Java Programmer", /*twoCents: */ "Java would be even cooler with Ada95's " + "generics, enumerated types, function types, " + "named parameter passing, etc...", /*disclaimer:*/ "These views not packaged in COM.ti.dseg.ac3i, " + "so loading them throws DontQuoteMeError. :-)" );