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=unavailable autolearn_force=no version=3.4.4 Path: border2.nntp.dca1.giganews.com!nntp.giganews.com!newspeer1.nac.net!feeder.erje.net!eu.feeder.erje.net!news.albasani.net!news.ecp.fr!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Rationale for this not to compile? Date: Fri, 25 Jul 2014 00:29:03 -0500 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: <1cb91e6a-9e49-4bc8-bf4a-67a16a00e3a0@googlegroups.com> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: loke.gir.dk 1406266144 11857 69.95.181.76 (25 Jul 2014 05:29:04 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Fri, 25 Jul 2014 05:29:04 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Xref: number.nntp.dca.giganews.com comp.lang.ada:187849 Date: 2014-07-25T00:29:03-05:00 List-Id: "Adam Beneschan" wrote in message news:1cb91e6a-9e49-4bc8-bf4a-67a16a00e3a0@googlegroups.com... >On Thursday, July 24, 2014 1:53:32 PM UTC-7, Victor Porton wrote: >> Is there any rationale why this does not compile? > >A generic instantiation is equivalent to "the instance declaration ... >immediately followed >by the instance body, both at the place of the instantiation." (12.3(12)) >Since the body >could contain code that depends on the representation of X already being >determined, >but it hasn't yet, the language makes this illegal. At least I think >that's the rationale. >AARM section 13.14, which discusses the freezing rules, explains in more >detail why >types have to be completely defined before they're used in certain cases >(see > http://www.ada-auth.org/standards/12aarm/html/AA-13-14.html). That's a pretty good explanation. We (the ARG) have spent dozens of hours attempting to find a way to allow something like the OPs example. (There's something like 10 AIs associated with that.) Each solution had some sort of fatal flaw (implementability, maintenance problems, too hard to use, etc.) The best solution is the put the instance into a child package; one of the reasons that we didn't adopt any of the ugly solutions is that using a child package often works fine and an ugly solution doesn't seem worth it in that case. In the special case where the generic has little implementation of it's own (a signature package), one can use a formal incomplete type as the formal type; it does allow an instantiation like the one the OP wrote. Specifically: package OK_Test is generic type T; package Gen is end Gen; type X is private; package Instance is new Gen(X); private type X is null record; end OK_Test; is legal. But the use of the formal incomplete type strongly restricts what you can do in the generic unit (because it's an incomplete type, and those allow very limited uses). One of my pet projects (that I don't have any time to follow up on!) is to create a useful container where the element type is a formal incomplete type. I think that the container would have to manage elements that live elsewhere (unlike Ada.Containers) -- since element creation isn't possible, but this would allow a container of limited elements, and of course would allow instantiation by a private type as here. Randy. > If it compiled, it would > be probably useful in practice with a real example similar to the below > toy > example (as to make the type T not private, I must create an *.Internal.* > package to serve as a "private repository" for types like T, as real > private > types cannot be used). It is called a hack. > > gnatmake -q -c -gnatc -u -P/home/porton/t/default.gpr test.ads > test.ads:10:32: premature use of private type > gnatmake: "/home/porton/t/test.ads" compilation error > > package Test is > > generic > type T is limited private; > package Gen is > end Gen; > > type X is private; > > package Instance is new Gen(X); > > private > type X is null record; > end Test;