* Indefinite Containers of Indefinite Private Types @ 2015-08-04 2:23 Jeffrey R. Carter 2015-08-04 5:40 ` Niklas Holsti 0 siblings, 1 reply; 10+ messages in thread From: Jeffrey R. Carter @ 2015-08-04 2:23 UTC (permalink / raw) This is legal: package Indefinite1 is type T (<>) is private; private -- Indefinite1 type T is new String; end Indefinite1; with Indefinite1; with Ada.Containers.Indefinite_Vectors; package Indefinite2 is use type Indefinite1.T; package Lists is new Ada.Containers.Indefinite_Vectors (Index_Type => Positive, Element_Type => Indefinite1.T); end Indefinite2; But this isn't: with Ada.Containers.Indefinite_Vectors; package Indefinite1 is type T (<>) is private; private -- Indefinite1 package Lists is new Ada.Containers.Indefinite_Vectors (Index_Type => Positive, Element_Type => T); type T is new String; end Indefinite1; It seems to me that both instantiations have all the information they need. Probably I'm missing something, but why is the latter illegal? -- Jeff Carter "English bed-wetting types." Monty Python & the Holy Grail 15 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-04 2:23 Indefinite Containers of Indefinite Private Types Jeffrey R. Carter @ 2015-08-04 5:40 ` Niklas Holsti 2015-08-04 18:56 ` Jeffrey R. Carter 0 siblings, 1 reply; 10+ messages in thread From: Niklas Holsti @ 2015-08-04 5:40 UTC (permalink / raw) On 15-08-04 05:23 , Jeffrey R. Carter wrote: > This is legal: > > package Indefinite1 is > type T (<>) is private; > private -- Indefinite1 > type T is new String; > end Indefinite1; > > with Indefinite1; > with Ada.Containers.Indefinite_Vectors; > > package Indefinite2 is > use type Indefinite1.T; > > package Lists is new Ada.Containers.Indefinite_Vectors > (Index_Type => Positive, Element_Type => Indefinite1.T); > end Indefinite2; > > But this isn't: > > with Ada.Containers.Indefinite_Vectors; > > package Indefinite1 is > type T (<>) is private; > private -- Indefinite1 > package Lists is new Ada.Containers.Indefinite_Vectors > (Index_Type => Positive, Element_Type => T); > > type T is new String; > end Indefinite1; > > It seems to me that both instantiations have all the information they need. > Probably I'm missing something, but why is the latter illegal? I'm not sure that I have understood your question correctly -- are you asking for the RM rule that makes this illegal, or for the reason behind that rule? At the point of instantiation in the second case, "T" is a partial view of the type. RM 7.3(5) says "... Similarly, before the full declaration, the name of the partial view cannot be used in a generic_instantiation or in a representation item." As to why this rule exists, I suspect it has to do with the "rechecks" discussed in the annotated RM 12.3(11) where the legality of an instantiation is checked by comparing the actual types with the _full_ declaration of the generic (not only with the declarations of the generic formals). It might be difficult to apply these rechecks if the actual type is only a partial view. The second case becomes legal if the full declaration of type T is moved to occur before the instantiation -- as happens in the first case -- but you probably knew that. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-04 5:40 ` Niklas Holsti @ 2015-08-04 18:56 ` Jeffrey R. Carter 2015-08-04 20:47 ` Randy Brukardt 2015-08-07 20:13 ` Bob Duff 0 siblings, 2 replies; 10+ messages in thread From: Jeffrey R. Carter @ 2015-08-04 18:56 UTC (permalink / raw) On 08/03/2015 10:40 PM, Niklas Holsti wrote: > > I'm not sure that I have understood your question correctly -- are you asking > for the RM rule that makes this illegal, or for the reason behind that rule? Sorry if I was unclear. I know the ARM prohibits using an uncompleted private type as the actual for a generic formal. I'm wondering why this applies to the case of a generic formal indefinite private type. Reading that leads me to think that I should have used a subject referring to generic formal indefinite private types rather than indefinite containers. > At the point of instantiation in the second case, "T" is a partial view of the > type. RM 7.3(5) says "... Similarly, before the full declaration, the name of > the partial view cannot be used in a generic_instantiation or in a > representation item." Right. This rule has the advantage of being simple. It seems to me it may have the disadvantage of disallowing feasible instantiations. > As to why this rule exists, I suspect it has to do with the "rechecks" discussed > in the annotated RM 12.3(11) where the legality of an instantiation is checked > by comparing the actual types with the _full_ declaration of the generic (not > only with the declarations of the generic formals). It might be difficult to > apply these rechecks if the actual type is only a partial view. What a generic can do with a formal indefinite private type is quite limited. Nothing it can do seems to me to need to know the full type definition. Maybe I've overlooked something, or maybe there's a good reason why something I don't think needs the full definition actually does. I'm curious whether such instantiations could be legal, and what I missed if they can't. > The second case becomes legal if the full declaration of type T is moved to > occur before the instantiation -- as happens in the first case -- but you > probably knew that. Yes, of course. The examples are simplified from a more complex case where the container is used in the full type definition. This can be achieved by adding some additional code that is essentially noise, or by using access types. Avoiding access types is worth adding noise, but it would be nice if the noise were unnecessary. -- Jeff Carter "Have you gone berserk? Can't you see that that man is a ni?" Blazing Saddles 38 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-04 18:56 ` Jeffrey R. Carter @ 2015-08-04 20:47 ` Randy Brukardt 2015-08-04 20:56 ` Jeffrey R. Carter 2015-08-07 20:13 ` Bob Duff 1 sibling, 1 reply; 10+ messages in thread From: Randy Brukardt @ 2015-08-04 20:47 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message news:mpr1po$4sn$1@dont-email.me... > On 08/03/2015 10:40 PM, Niklas Holsti wrote: >> >> I'm not sure that I have understood your question correctly -- are you >> asking >> for the RM rule that makes this illegal, or for the reason behind that >> rule? > > Sorry if I was unclear. I know the ARM prohibits using an uncompleted > private > type as the actual for a generic formal. I'm wondering why this applies to > the > case of a generic formal indefinite private type. An amazing amount of ARG hair has been pulled over this issue. There are about 10 AIs on the topic, none of which have gotten particularly close to being accepted. The very short answer is that an object can be created of such a type, so it doesn't help that the type is indefinite (the problems with allowing this tend to be in freezing and elaboration rules, particularly in not changing the rules incompatibly). Specifically: generic type T (<>) is private; function Creator return T; package G is Obj : T := Creator; -- Legal. end G; Note that such an object would be illegal before the full completion of the private type. So, if you put that object declaration into the body, you have a contract model violation. Therein is the problem. One could imagine having a declaration for the generic (perhaps an aspect?) that would allow such instantiations (and disallow such objects), but again there has been little traction for such proposals, all of which are quite complex to describe and implement. ... >> At the point of instantiation in the second case, "T" is a partial view >> of the >> type. RM 7.3(5) says "... Similarly, before the full declaration, the >> name of >> the partial view cannot be used in a generic_instantiation or in a >> representation item." > > Right. This rule has the advantage of being simple. It seems to me it may > have > the disadvantage of disallowing feasible instantiations. Sure, but there can't be any objects in the generic. Even if there isn't a constructor function, any parameter of type T could have been used in "new". >> I suppose this to do with the "rechecks" discussed >> in the annotated RM 12.3(11) where the legality of an instantiation is >> checked >> by comparing the actual types with the _full_ declaration of the generic >> (not >> only with the declarations of the generic formals). It might be difficult >> to >> apply these rechecks if the actual type is only a partial view. > > What a generic can do with a formal indefinite private type is quite > limited. > Nothing it can do seems to me to need to know the full type definition. > Maybe > I've overlooked something, or maybe there's a good reason why something I > don't > think needs the full definition actually does. I'm curious whether such > instantiations could be legal, and what I missed if they can't. Declaring an object surely needs the full declaration, and I showed above how to do it. Recall that the elaboration of the body occurs at the point of the instance (before the full declaration of the private type). One can make signature packages with formal incomplete types (which can be instantiated with private types before the completion), but it's hard to make a useful container that way. (It's not impossible, but you have to use more access types than I find comfortable.) >> The second case becomes legal if the full declaration of type T is moved >> to >> occur before the instantiation -- as happens in the first case -- but you >> probably knew that. > > Yes, of course. The examples are simplified from a more complex case where > the > container is used in the full type definition. This can be achieved by > adding > some additional code that is essentially noise, or by using access types. > Avoiding access types is worth adding noise, but it would be nice if the > noise > were unnecessary. I agree, but the ARG has not been able to find an acceptable solution to this problem. And we surely have tried: AI95-00359-01, AI95-00359-02, AI95-00359-03, AI95-00359-04, AI05-0074-1, AI05-0074-2, AI05-0074-3, AI05-0074-4, AI05-0074-5 (AI05-0011-1 was also related, but it was a duplicate). We're pretty much pooped out on this topic. Sometimes there just is no answer that can get a consensus. Randy. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-04 20:47 ` Randy Brukardt @ 2015-08-04 20:56 ` Jeffrey R. Carter 2015-08-06 18:49 ` Randy Brukardt 0 siblings, 1 reply; 10+ messages in thread From: Jeffrey R. Carter @ 2015-08-04 20:56 UTC (permalink / raw) On 08/04/2015 01:47 PM, Randy Brukardt wrote: > > An amazing amount of ARG hair has been pulled over this issue. There are > about 10 AIs on the topic, none of which have gotten particularly close to > being accepted. > > The very short answer is that an object can be created of such a type, so it > doesn't help that the type is indefinite (the problems with allowing this > tend to be in freezing and elaboration rules, particularly in not changing > the rules incompatibly). > > Specifically: > > generic > type T (<>) is private; > function Creator return T; > package G is > Obj : T := Creator; -- Legal. > end G; > > Note that such an object would be illegal before the full completion of the > private type. So, if you put that object declaration into the body, you have > a contract model violation. Therein is the problem. Of course. I guess I was thinking too much in terms of what a container does with the type and not in general. > One could imagine having a declaration for the generic (perhaps an aspect?) > that would allow such instantiations (and disallow such objects), but again > there has been little traction for such proposals, all of which are quite > complex to describe and implement. I can guess so. Probably a new generic formal type would be desired. Meanwhile I'll put up with the noise. -- Jeff Carter "Have you gone berserk? Can't you see that that man is a ni?" Blazing Saddles 38 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-04 20:56 ` Jeffrey R. Carter @ 2015-08-06 18:49 ` Randy Brukardt 2015-08-06 20:12 ` Jeffrey R. Carter 0 siblings, 1 reply; 10+ messages in thread From: Randy Brukardt @ 2015-08-06 18:49 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message news:mpr8rn$33n$1@dont-email.me... > On 08/04/2015 01:47 PM, Randy Brukardt wrote: ... >> One could imagine having a declaration for the generic (perhaps an >> aspect?) >> that would allow such instantiations (and disallow such objects), but >> again >> there has been little traction for such proposals, all of which are quite >> complex to describe and implement. > > I can guess so. Probably a new generic formal type would be desired. > Meanwhile > I'll put up with the noise. That's one possibility. We could call it a generic private type. Oops -- that name is taken, and alternative names are annoying. (The idea of course would be similar to the generic incomplete type; the restrictions on the use of a private type would be enforced on the uses of the generic formal type.) We've also looked at declarations (maybe an aspect) for the generic as a whole, there was a proposal for a "forward" declaration for the generic (that is, you'd be able to separate the visible part of the generic from the actual instance, just like in other kinds of packages), and a proposal to change the freezing to be exactly like a macro (meaning a break in the contract model, and a horror to implement on top of that). We also found that there is a workaround of sorts using a child package to hold the instantiation, which works so long as the private type doesn't use something from the instantiation (usually a cursor for a container) in its full declaration. The existence of the workaround lowers the priority of finding a fix, and given the difficulty of doing so, we pretty much gave up. I'm sure we'll revisit it someday. Randy. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-06 18:49 ` Randy Brukardt @ 2015-08-06 20:12 ` Jeffrey R. Carter 2015-08-07 19:49 ` Randy Brukardt 0 siblings, 1 reply; 10+ messages in thread From: Jeffrey R. Carter @ 2015-08-06 20:12 UTC (permalink / raw) On 08/06/2015 11:49 AM, Randy Brukardt wrote: > > That's one possibility. We could call it a generic private type. Oops -- > that name is taken, and alternative names are annoying. (The idea of course > would be similar to the generic incomplete type; the restrictions on the use > of a private type would be enforced on the uses of the generic formal type.) > > We've also looked at declarations (maybe an aspect) for the generic as a > whole, there was a proposal for a "forward" declaration for the generic > (that is, you'd be able to separate the visible part of the generic from the > actual instance, just like in other kinds of packages), and a proposal to > change the freezing to be exactly like a macro (meaning a break in the > contract model, and a horror to implement on top of that). We also found > that there is a workaround of sorts using a child package to hold the > instantiation, which works so long as the private type doesn't use something > from the instantiation (usually a cursor for a container) in its full > declaration. The existence of the workaround lowers the priority of finding > a fix, and given the difficulty of doing so, we pretty much gave up. I'm > sure we'll revisit it someday. I looked at some of the AIs you mentioned and saw there were a number of ideas. The child-pkg workaround involves using an access type, so it doesn't seem to gain anything over using access types directly, and is less attractive than access-free noise, which seems to me to be another work around not considered in the discussion I looked at. The problem seems to be that there is a single instantiation for both the spec and body, and the body occurs and is elaborated immediately at the point of the instantiation. Another language might instantiate the spec and body separately, allowing the body to be instantiated after the full type. There were some suggestions in the AIs along that line, but couched in terms of delaying freezing rather than separation of spec and body. Maybe something like package P is type T (<>) is private; private package Lists is new Indefinite_Vectors (Index_Type => Positive, Element_Type => T) with not body; type T is record List : Lists.Vector; end record; end P; package body P is package body Lists is new Indefinite_Vectors; ... I guess I'm beating a dead hippopotamus here. -- Jeff Carter "Facts do not cease to exist because they are ignored." Aldous Huxley 134 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-06 20:12 ` Jeffrey R. Carter @ 2015-08-07 19:49 ` Randy Brukardt 0 siblings, 0 replies; 10+ messages in thread From: Randy Brukardt @ 2015-08-07 19:49 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message news:mq0f0g$7im$1@dont-email.me... > On 08/06/2015 11:49 AM, Randy Brukardt wrote: >> >> That's one possibility. We could call it a generic private type. Oops -- >> that name is taken, and alternative names are annoying. (The idea of >> course >> would be similar to the generic incomplete type; the restrictions on the >> use >> of a private type would be enforced on the uses of the generic formal >> type.) >> >> We've also looked at declarations (maybe an aspect) for the generic as a >> whole, there was a proposal for a "forward" declaration for the generic >> (that is, you'd be able to separate the visible part of the generic from >> the >> actual instance, just like in other kinds of packages), and a proposal to >> change the freezing to be exactly like a macro (meaning a break in the >> contract model, and a horror to implement on top of that). We also found >> that there is a workaround of sorts using a child package to hold the >> instantiation, which works so long as the private type doesn't use >> something >> from the instantiation (usually a cursor for a container) in its full >> declaration. The existence of the workaround lowers the priority of >> finding >> a fix, and given the difficulty of doing so, we pretty much gave up. I'm >> sure we'll revisit it someday. > > I looked at some of the AIs you mentioned and saw there were a number of > ideas. > The child-pkg workaround involves using an access type, so it doesn't seem > to > gain anything over using access types directly, and is less attractive > than > access-free noise, which seems to me to be another work around not > considered in > the discussion I looked at. > > The problem seems to be that there is a single instantiation for both the > spec > and body, and the body occurs and is elaborated immediately at the point > of the > instantiation. Another language might instantiate the spec and body > separately, > allowing the body to be instantiated after the full type. There were some > suggestions in the AIs along that line, but couched in terms of delaying > freezing rather than separation of spec and body. > > Maybe something like > > package P is > type T (<>) is private; > private > package Lists is new Indefinite_Vectors > (Index_Type => Positive, Element_Type => T) > with not body; > > type T is record > List : Lists.Vector; > end record; > end P; > > package body P is > package body Lists is new Indefinite_Vectors; > ... I had suggested something along this line (not exactly this, though), but at least some people were trying to do this without making any work for the client. But of course that causes incompatibilties; which led to arguments about how important the incompatibilities are, and that tends to lead nowhere. > I guess I'm beating a dead hippopotamus here. Yup. Randy. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-04 18:56 ` Jeffrey R. Carter 2015-08-04 20:47 ` Randy Brukardt @ 2015-08-07 20:13 ` Bob Duff 2015-08-07 20:45 ` Jeffrey R. Carter 1 sibling, 1 reply; 10+ messages in thread From: Bob Duff @ 2015-08-07 20:13 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes: > Yes, of course. The examples are simplified from a more complex case where the > container is used in the full type definition. This can be achieved by adding > some additional code that is essentially noise, or by using access types. > Avoiding access types is worth adding noise, but it would be nice if the noise > were unnecessary. I'm curious what the "noise" looks like in your case. Last time I ran into this problem I think I ended up using a workaround that involved access types. I don't remember the details. - Bob ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Indefinite Containers of Indefinite Private Types 2015-08-07 20:13 ` Bob Duff @ 2015-08-07 20:45 ` Jeffrey R. Carter 0 siblings, 0 replies; 10+ messages in thread From: Jeffrey R. Carter @ 2015-08-07 20:45 UTC (permalink / raw) On 08/07/2015 01:13 PM, Bob Duff wrote: > "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes: > >> Yes, of course. The examples are simplified from a more complex case where the >> container is used in the full type definition. This can be achieved by adding >> some additional code that is essentially noise, or by using access types. >> Avoiding access types is worth adding noise, but it would be nice if the noise >> were unnecessary. > > I'm curious what the "noise" looks like in your case. > > Last time I ran into this problem I think I ended up using a workaround > that involved access types. I don't remember the details. It involves using tagged types, type extension, and a container of a class-wide type: with Ada.Containers.Indefinite_Vectors; package P is type T (<>) is private; private type Root is tagged null record; package Lists is new Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Root'Class); type T is new Root with record List : Lists.Vector; end T; end P; The only reason for the type extension is to get the instantiation that can be used in the full declaration of T. The only objects that will be stored in a vector are of type T. In addition to the noise of the Root type and the extension for T, there are type conversions required that are part of the noise. -- Jeff Carter "From this day on, the official language of San Marcos will be Swedish." Bananas 28 ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-08-07 20:45 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-08-04 2:23 Indefinite Containers of Indefinite Private Types Jeffrey R. Carter 2015-08-04 5:40 ` Niklas Holsti 2015-08-04 18:56 ` Jeffrey R. Carter 2015-08-04 20:47 ` Randy Brukardt 2015-08-04 20:56 ` Jeffrey R. Carter 2015-08-06 18:49 ` Randy Brukardt 2015-08-06 20:12 ` Jeffrey R. Carter 2015-08-07 19:49 ` Randy Brukardt 2015-08-07 20:13 ` Bob Duff 2015-08-07 20:45 ` Jeffrey R. Carter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox