* Rationale for this not to compile? @ 2014-07-24 20:53 Victor Porton 2014-07-24 21:36 ` Adam Beneschan 2014-07-25 13:18 ` Victor Porton 0 siblings, 2 replies; 9+ messages in thread From: Victor Porton @ 2014-07-24 20:53 UTC (permalink / raw) Is there any rationale why this does not compile? 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; -- Victor Porton - http://portonvictor.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-24 20:53 Rationale for this not to compile? Victor Porton @ 2014-07-24 21:36 ` Adam Beneschan 2014-07-25 5:29 ` Randy Brukardt 2014-07-25 13:18 ` Victor Porton 1 sibling, 1 reply; 9+ messages in thread From: Adam Beneschan @ 2014-07-24 21:36 UTC (permalink / raw) 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). -- Adam > 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; ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-24 21:36 ` Adam Beneschan @ 2014-07-25 5:29 ` Randy Brukardt 2014-07-25 12:19 ` Victor Porton 2014-07-25 14:40 ` Robert A Duff 0 siblings, 2 replies; 9+ messages in thread From: Randy Brukardt @ 2014-07-25 5:29 UTC (permalink / raw) "Adam Beneschan" <adambeneschan@gmail.com> 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; ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-25 5:29 ` Randy Brukardt @ 2014-07-25 12:19 ` Victor Porton 2014-07-25 12:35 ` AdaMagica 2014-07-25 14:40 ` Robert A Duff 1 sibling, 1 reply; 9+ messages in thread From: Victor Porton @ 2014-07-25 12:19 UTC (permalink / raw) Randy Brukardt wrote: > > "Adam Beneschan" <adambeneschan@gmail.com> 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; Sorry for a stupid question: What is the difference of: generic type T package Gen is end Gen; and generic type T is private package Gen is end Gen; -- Victor Porton - http://portonvictor.org ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-25 12:19 ` Victor Porton @ 2014-07-25 12:35 ` AdaMagica 0 siblings, 0 replies; 9+ messages in thread From: AdaMagica @ 2014-07-25 12:35 UTC (permalink / raw) generic type T; -- an incomplete type package Gen is end Gen; An incomplete type is - ahem - incomplete, the compiler does not and cannot know anything about it. It must later be completed somewhere in the code. Thus very little can be done in the body of the generic with an incomplete type (e.g. no assignment). It's like type T; type T_Ptr is access T; type T is ... generic type T is private; -- a private type package Gen is end Gen; The compiler may make assumptions about the type, e.g. object declaration and assignment are possible. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-25 5:29 ` Randy Brukardt 2014-07-25 12:19 ` Victor Porton @ 2014-07-25 14:40 ` Robert A Duff 2014-07-25 19:45 ` Randy Brukardt 1 sibling, 1 reply; 9+ messages in thread From: Robert A Duff @ 2014-07-25 14:40 UTC (permalink / raw) "Randy Brukardt" <randy@rrsoftware.com> writes: > 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. Sounds interesting, but I don't understand what you mean by "live elsewhere". Could you outline how this would work? I'm having trouble seeing what use is a "container" that doesn't contain any elements. - Bob ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-25 14:40 ` Robert A Duff @ 2014-07-25 19:45 ` Randy Brukardt 2014-07-25 20:33 ` Robert A Duff 0 siblings, 1 reply; 9+ messages in thread From: Randy Brukardt @ 2014-07-25 19:45 UTC (permalink / raw) "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message news:wccvbql5won.fsf@shell01.TheWorld.com... > "Randy Brukardt" <randy@rrsoftware.com> writes: > >> 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. > > Sounds interesting, but I don't understand what you mean by "live > elsewhere". Could you outline how this would work? I'm having trouble > seeing what use is a "container" that doesn't contain any elements. I left out one part: the elements would have to be tagged, because "tagged incomplete" allows a number of things that regular incomplete doesn't. (In particular, they're assumed to be passed by-reference, so parameters are allowed). Access after insertion would be via Reference/Constant_Reference only (can't make a copy of the element, obviously, and no functions can return the element). Anyway, you can't create an object of an incomplete type, so the client has to do that before adding it to the container. That means the container's job is to manage the relationships between the elements (and the lookup mechanism, for maps and sets). For instance, one could have a bunch of tasks, and put them into a map container in order to add a lookup mechanism to them. Something like: Tasks : array (1 .. 10) of My_Task; -- Assume My_Task is tagged. package My_Task_Map is new Randys_Super_Duper_Map_Container (String, My_Task); My_Map : My_Task_Map.Map; ... My_Map.Insert ("Bob", Tasks(1)); My_Map.Insert ("Randy", Tasks(2)); My_Map.Insert ("Tucker", Tasks(3)); My_Map.Insert ("Steve", Tasks(4)); -- My_Map("Bob").My_Entry (...); -- Entry call on the task associated with "Bob". Does this make sense? Randy. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-25 19:45 ` Randy Brukardt @ 2014-07-25 20:33 ` Robert A Duff 0 siblings, 0 replies; 9+ messages in thread From: Robert A Duff @ 2014-07-25 20:33 UTC (permalink / raw) "Randy Brukardt" <randy@rrsoftware.com> writes: > Does this make sense? Yes, I think so. Interesting idea. - Bob ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Rationale for this not to compile? 2014-07-24 20:53 Rationale for this not to compile? Victor Porton 2014-07-24 21:36 ` Adam Beneschan @ 2014-07-25 13:18 ` Victor Porton 1 sibling, 0 replies; 9+ messages in thread From: Victor Porton @ 2014-07-25 13:18 UTC (permalink / raw) Victor Porton wrote: > Is there any rationale why this does not compile? 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; My specific problem was solved replacing generic type T is limited private; with generic type T; -- Victor Porton - http://portonvictor.org ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-07-25 20:33 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-07-24 20:53 Rationale for this not to compile? Victor Porton 2014-07-24 21:36 ` Adam Beneschan 2014-07-25 5:29 ` Randy Brukardt 2014-07-25 12:19 ` Victor Porton 2014-07-25 12:35 ` AdaMagica 2014-07-25 14:40 ` Robert A Duff 2014-07-25 19:45 ` Randy Brukardt 2014-07-25 20:33 ` Robert A Duff 2014-07-25 13:18 ` Victor Porton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox