* Design Question: How Best To Structure Cross-Referencing Types In Ada 95 @ 1999-01-20 0:00 Anthony E. Glover 1999-01-21 0:00 ` dewar ` (3 more replies) 0 siblings, 4 replies; 10+ messages in thread From: Anthony E. Glover @ 1999-01-20 0:00 UTC (permalink / raw) [-- Attachment #1: Type: text/plain, Size: 1130 bytes --] Just recently switched our development environment to Ada95 and have come across a problem that may lend itself to some new Ada95 capability. I have some new code that has private types that reference each other. In Ada83 I have something that looks like: package XYZ is type Part is private; type Car is private; procedure Install( On_Car : Car; The_Part : Part ); procedure Activate( The_Part : Part ); private type Part is record Parent_Car : Car; end record; type Car is record Part1 : Part; Part2 : Part; end record; end XYZ; Since both types and some of the subprograms reference each other, I have to put them both in the same package. It turns out that I have about 5 types that behave like this and I end up with one large package. I would rather have the types split into different packages, but I would get circular dependencies when compiling the specs. Is there a neat Ada95 way of getting around this cross-referencing problem? Tony aeg@hiwaay.net glover@thaad.tecmasters.com -- Tony Glover ELMCO, Inc. (256)721-6317 aeg@hiwaay.net [-- Attachment #2: Card for Anthony E. Glover --] [-- Type: text/x-vcard, Size: 274 bytes --] begin: vcard fn: Anthony E. Glover n: Glover;Anthony E. org: ELMCO, Inc. email;internet: aeg@hiwaay.net title: Senior Software Engineer x-mozilla-cpt: ;0 x-mozilla-html: FALSE version: 2.1 end: vcard ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-20 0:00 Design Question: How Best To Structure Cross-Referencing Types In Ada 95 Anthony E. Glover @ 1999-01-21 0:00 ` dewar 1999-01-21 0:00 ` Brian Rogoff 1999-01-26 0:00 ` Dale Stanbrough 1999-01-21 0:00 ` Matthew Heaney ` (2 subsequent siblings) 3 siblings, 2 replies; 10+ messages in thread From: dewar @ 1999-01-21 0:00 UTC (permalink / raw) In article <36A68FCA.E1EEAFFE@hiwaay.net>, aeg@hiwaay.net, glover@thaad.tecmasters.com wrote: > This is a multi-part message in MIME format. > --------------6448902F32C077DF069276B5 > Content-Type: text/plain; charset=us-ascii > Content-Transfer-Encoding: 7bit > Since both types and some of the subprograms reference > each other, I have to put them both in the same package. > It turns out that I have about 5 types that > behave like this and I end up with one large package. I > would rather have the types split into different > packages, but I would get circular dependencies when > compiling the specs. > > Is there a neat Ada95 way of getting around this > cross-referencing problem? This is an old and well discussed problem. Often you can introduce a third package with the types alone to at least factor this out, but the fundamental circularity problem remains and there is no solution in pure Ada 95. For JGNAT, the version of GNAT that generates code for the JVM, we have found it important to deal with this problem for the purpose of translating existing Java specs. We have therefore implemented an extension, based on Tucker's "with type" suggestion the last time around this was discussed, and this extension will be available (controlled by a switch of course) in version 3.12 of GNAT. There are not many places where one can justify out and out extensions of the language (and indeed I suppose one could do this with a pragma, but it seems silly). This however, seems an exception, where an extension is really needed. Robert Dewar Ada Core Technologies -----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-21 0:00 ` dewar @ 1999-01-21 0:00 ` Brian Rogoff 1999-01-26 0:00 ` Dale Stanbrough 1 sibling, 0 replies; 10+ messages in thread From: Brian Rogoff @ 1999-01-21 0:00 UTC (permalink / raw) On Thu, 21 Jan 1999 dewar@gnat.com wrote: > In article aeg@hiwaay.net, glover@thaad.tecmasters.com wrote: > > > > ... Ada withing problem description snipped ... > > Is there a neat Ada95 way of getting around this > > cross-referencing problem? > > This is an old and well discussed problem. Often you can > introduce a third package with the types alone to at least > factor this out, but the fundamental circularity problem > remains and there is no solution in pure Ada 95. > > For JGNAT, the version of GNAT that generates code for the > JVM, we have found it important to deal with this problem > for the purpose of translating existing Java specs. We have > therefore implemented an extension, based on Tucker's "with > type" suggestion the last time around this was discussed, > and this extension will be available (controlled by a > switch of course) in version 3.12 of GNAT. Is your extension going to use the same syntax as Tucker's proposal? Matthew Heaney raised the objection that the syntax was a bit ugly, since "with type" : "use type" is not the same relationship as "with" : "use" (am I paraphrasing your objection correctly Matthew?) and so a better syntax should be designed. I kind of agree, but I think the problem is more with "use type", which I don't like. Maybe next we'll see the signature extension from GNU-C++ on GNAT so that we can write Java interface style code directly ;-). > There are not many places where one can justify out and out > extensions of the language (and indeed I suppose one could > do this with a pragma, but it seems silly). This however, > seems an exception, where an extension is really needed. I thought ACT had a pragma for this; I recall reading about it from ACT-Europe. -- Brian ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-21 0:00 ` dewar 1999-01-21 0:00 ` Brian Rogoff @ 1999-01-26 0:00 ` Dale Stanbrough 1 sibling, 0 replies; 10+ messages in thread From: Dale Stanbrough @ 1999-01-26 0:00 UTC (permalink / raw) Robert Dewar wrote... > For JGNAT, the version of GNAT that generates code for the > JVM, we have found it important to deal with this problem > for the purpose of translating existing Java specs. We have > therefore implemented an extension, based on Tucker's "with > type" suggestion the last time around this was discussed, > and this extension will be available (controlled by a > switch of course) in version 3.12 of GNAT. I was wondering how you would get around this problem. I suppose the important questions to ask are * Is this change integrated into your implementation of ASIS? * Is it likely that other compiler vendors will implement it (i presume you have talked to them about it) * When will gnat 3.12p be released ;-) (someone had to be first to ask!) If we can get everyone to implement it, it would make the ugly hack for CORBA (cleverly invented by John Volan if I remember correctly) no longer necessary. Dale ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-20 0:00 Design Question: How Best To Structure Cross-Referencing Types In Ada 95 Anthony E. Glover 1999-01-21 0:00 ` dewar @ 1999-01-21 0:00 ` Matthew Heaney 1999-01-30 0:00 ` Nick Roberts 1999-01-21 0:00 ` dennison 1999-01-22 0:00 ` Steve Whalen 3 siblings, 1 reply; 10+ messages in thread From: Matthew Heaney @ 1999-01-21 0:00 UTC (permalink / raw) "Anthony E. Glover" <aeg@hiwaay.net> writes: > Is there a neat Ada95 way of getting around this cross-referencing > problem? You have to forward declare one of the types, which you'll have to make tagged: package Root_Cars is type Root_Car is abstract tagged null record; end Root_Cars; with Root_Cars; use Root_Cars; package Parts is type Part is private; procedure Activate (The_Part : Part); private type Car_Access is access all Root_Car'Class; type Part is record Parent_Car : Car_Access; end record; end Parts; with Root_Cars; use Root_Cars; with Parts; use Parts; package Cars is type Car is new Root_Car with private; procedure Install (On : Car; The_Part : Part); private type Car is record Part1 : Part; Part2 : Part; end record; end Cars; Now, in the body of Parts, just down-cast to the normal car type: with Cars; package body Parts is procedure Activate (The_Part : in Part) is The_Car : Car renames Car (The_Part.Car.all); begin ... end; end Parts; You don't have to worry the Tag_Check failing, because only type Cars.Car derives from Root_Cars.Root_Car. If this check bothers you, then just disable it: procedure Activate (The_Part : in Part) is pragma Suppress (Tag_Check); The_Car : Car renames Car (The_Part.Car.all); begin ... end; ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-21 0:00 ` Matthew Heaney @ 1999-01-30 0:00 ` Nick Roberts 1999-01-31 0:00 ` Matthew Heaney 0 siblings, 1 reply; 10+ messages in thread From: Nick Roberts @ 1999-01-30 0:00 UTC (permalink / raw) Great minds must think alike! (He says modestly :-) I was _just_ about to suggest (more or less) the same solution. Matthew says "You have to ...": I would suggest that this is a _possible_ solution, rather than _the_ solution. It might (but not necessarily) be appropriate to organise the packages a little, e.g. by making Cars, Parts etc. children of Root_Cars. As a tiny matter of style, you might want to choose names thusly: "Cars" instead of "Root_Cars", and then "Ford_Cars", "GM_Cars", "BMW_Cars", "Ford_Parts", "Lucas_Parts", etc. instead of "Cars", "Parts", etc. (i.e. the children packages with derived types are progressively _specialising_). [I've no doubt Matt chose the names he did to simplify the example.] This design (with tagged types) gives you the extensibility that OO people are always banging on about: you can add a new type of car or part without (in general) having to recompile any of the other packages. On larger systems this can help prevent you wearing your teeth down on the edge of the desk (waiting to recompile). In implementation terms, the tag check costs about 5-10 instructions, and about 2-4 clock ticks for success (on a typical modern 32-bit processor, with Optimise(Time) in force, excluding crap compilers). Unless you have a really good reason not to, I would suggest you just live with this check: it is likely to save you being skewered by a deep bug one day. ------------------------------------------- Nick Roberts ------------------------------------------- Matthew Heaney wrote: a tagged-type solution to Tony's problem. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-30 0:00 ` Nick Roberts @ 1999-01-31 0:00 ` Matthew Heaney 0 siblings, 0 replies; 10+ messages in thread From: Matthew Heaney @ 1999-01-31 0:00 UTC (permalink / raw) "Nick Roberts" <Nick.Roberts@dial.pipex.com> writes: > It might (but not necessarily) be appropriate to organise the packages a > little, e.g. by making Cars, Parts etc. children of Root_Cars. I don't agree, because the package Root_Cars is intended only as a work-around, not as a "real" package. If you pretend for the moment that Ada doesn't have this "problem," then you would structure the packages with package Cars as the root of the subsystem. The package Root_Cars isn't part of the package hierarchy. It exists only to serve as the home for the forward declaration of a type, a declaration unnecessary in a "better" version of the language. > As a tiny matter of style, you might want to choose names thusly: > "Cars" instead of "Root_Cars", and then "Ford_Cars", "GM_Cars", > "BMW_Cars", "Ford_Parts", "Lucas_Parts", etc. instead of "Cars", > "Parts", etc. (i.e. the children packages with derived types are > progressively _specialising_). [I've no doubt Matt chose the names he > did to simplify the example.] Just so there's no confusion about my solution: type Cars.Car is the ONLY type that derives from Root_Car. The type Car, NOT Root_Car, is the "real" root of the hierarchy. That Car derives from Root_Car is sort of an implementation detail that we had to show in the spec. This point is perhaps made more clear using a different name: package Forward_Declaration_Of_Type_Cars_Dot_Car is type Parent_Of_Type_Cars_Dot_Car_ONLY is abstract tagged null record; end; with Forward_Declaration_Of_Type_Cars_Dot_Car; use ... package Cars is type Car is new Parent_Of_Type_Cars_Dot_Car_ONLY with private; ... end Cars; Specialized cars would be declared in children of package Cars, which is the root of the package hierarchy. > This design (with tagged types) gives you the extensibility that OO people > are always banging on about: you can add a new type of car or part without > (in general) having to recompile any of the other packages. On larger > systems this can help prevent you wearing your teeth down on the edge of the > desk (waiting to recompile). But realize that we only made this type tagged because we needed to forward declare the Car type, because of a mutual dependency between specs. We used a tagged type because there is no other way to effect the work-around. In a slightly different language, type Car wouldn't have to be tagged. Not every abstraction has to be implemented as a tagged type. I avoid making a type tagged, unless I have a good reason to (because it's part of a type hierarchy). > In implementation terms, the tag check costs about 5-10 instructions, and > about 2-4 clock ticks for success (on a typical modern 32-bit processor, > with Optimise(Time) in force, excluding crap compilers). Unless you have a > really good reason not to, I would suggest you just live with this check: it > is likely to save you being skewered by a deep bug one day. But that would mean a developer was breaking a rule (that isn't enforceable by the language), by deriving from the abstract parent type of type Car. I wouldn't call this a "deep bug." Rather, it's a symptom of the programmer's unfamiliarity with the idiom of how to simulate mutual dependencies between package specs. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-20 0:00 Design Question: How Best To Structure Cross-Referencing Types In Ada 95 Anthony E. Glover 1999-01-21 0:00 ` dewar 1999-01-21 0:00 ` Matthew Heaney @ 1999-01-21 0:00 ` dennison 1999-01-22 0:00 ` Steve Whalen 3 siblings, 0 replies; 10+ messages in thread From: dennison @ 1999-01-21 0:00 UTC (permalink / raw) In article <36A68FCA.E1EEAFFE@hiwaay.net>, aeg@hiwaay.net, glover@thaad.tecmasters.com wrote: > In Ada83 I have something that looks like: > > package XYZ is ... > type Part is > record > Parent_Car : Car; > end record; > type Car is > record > Part1 : Part; > Part2 : Part; > end record; > end XYZ; > Not too much like this I hope. Elaboration of this would involve infinite mutual recursion! I think its safe to assume that at least one of these (probably Parent_Car) is actually a *pointer* to the other. > behave like this and I end up with one large package. I would rather > have the > types split into different packages, but I would get circular > dependencies when > compiling the specs. > > Is there a neat Ada95 way of getting around this cross-referencing > problem? Not that I know of. I thought I heard somewhere that gnat may be able to handle two specs withing each other. That may solve part of your problem. T.E.D. -----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-20 0:00 Design Question: How Best To Structure Cross-Referencing Types In Ada 95 Anthony E. Glover ` (2 preceding siblings ...) 1999-01-21 0:00 ` dennison @ 1999-01-22 0:00 ` Steve Whalen 1999-01-22 0:00 ` dennison 3 siblings, 1 reply; 10+ messages in thread From: Steve Whalen @ 1999-01-22 0:00 UTC (permalink / raw) John Volan's "Ada95 With-ing Problem" site covers this problem at: http://www.bluemarble.net/~jvolan/WithingProblem/FAQ.html Steve -- {===--------------------------------------------------------------===} Steve Whalen swhalen@netcom.com {===--------------------------------------------------------------===} ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Design Question: How Best To Structure Cross-Referencing Types In Ada 95 1999-01-22 0:00 ` Steve Whalen @ 1999-01-22 0:00 ` dennison 0 siblings, 0 replies; 10+ messages in thread From: dennison @ 1999-01-22 0:00 UTC (permalink / raw) In article <swhalenF5yLGF.42H@netcom.com>, Steve Whalen <swhalen@netcom.com> wrote: > John Volan's "Ada95 With-ing Problem" site covers this problem at: > > http://www.bluemarble.net/~jvolan/WithingProblem/FAQ.html Wow! An extensive web page dedicated to a single FAQ. Cool. T.E.D. -----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~1999-01-31 0:00 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1999-01-20 0:00 Design Question: How Best To Structure Cross-Referencing Types In Ada 95 Anthony E. Glover 1999-01-21 0:00 ` dewar 1999-01-21 0:00 ` Brian Rogoff 1999-01-26 0:00 ` Dale Stanbrough 1999-01-21 0:00 ` Matthew Heaney 1999-01-30 0:00 ` Nick Roberts 1999-01-31 0:00 ` Matthew Heaney 1999-01-21 0:00 ` dennison 1999-01-22 0:00 ` Steve Whalen 1999-01-22 0:00 ` dennison
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox