!standard 13.13.2 (31) 01-02-15 AI95-00262/01 !standard 13.13.2 (34) !class amendment 01-02-15 !status work item 01-02-15 !status received 01-02-15 !priority Medium !difficulty Hard !subject Access to private units in the private part !summary !problem The private part of a package includes part of the implementation of the package. For instance, the components of a private type may include handles and other low-level data structures. Ada 95 provides private packages to organize the implementation of a subsystem. Unfortunately, these packages cannot be used in the private part of a public package - the context clause for the private package is illegal. This makes it difficult to use private packages to organize implementation details of a subsystem. For example, Claw puts most of the Win32 interface details into a set of private packages. However, the inability to use the contents of those packages in private parts meant that various workarounds had to be used: Some types were moved to the ultimate parent package (for instance, all of the handle types); Many parameters and constants were declared to be of predefined types, so that the predefined types could be used in the private part (thus losing the benefits of strong typing); Initializations of components were done in an Initialize routine in the package body (so that the constants declared in the private packages could be used). All of this bending of the design was necessary because private packages could not be used in the private part of a public package. !proposal (* Either "with private", or a separate compilation scheme for private parts; see appendix for rough proposals of each *) !discussion !example !ACATS test !appendix From: Randy Brukardt [Randy@RRSoftware.Com] Sent: Wednesday, February 14, 2001 1:54 PM A recent discussion on comp.lang.ada proposed a "with private" context clause, which would allow the withed entity to be used only in the private part of a package. The primary benefit of such a feature is that it would allow the use of private packages in the private part of a public package. This is currently impossible, and it forces reorganization of packages. For instance, originally in Claw we put the low-level Win32 interface in a series of private packages. However, these packages cannot be accessed in the private part of the public types. That means that either we had to avoid strong typing in the low-level interface, or abandon the private package structure. For instance, a possible image list package would look like: package Claw.Low_Level_Image_Lists is type HImage_List is new DWord; type IL_Flags is new UInt; ILR_DEFAULTCOLOR : constant IL_Flags := 16#0000#; ILR_MONOCHROME : constant IL_Flags := 16#0001#; ... type Image_Kind_Type is (Bitmap, Icon, Cursor); for Image_Kind_Type use (Bitmap => 0, Icon => 1, Cursor => 2); function Image_List_Load_Image ( Name : in Claw.Win32.LPCStr; Width : in Claw.Int; Image_Kind : in Image_Kind_Type; Flags : in IL_Flags) return HImage_List; pragma Import (StdCall, Image_List_Load_Image, "ImageList_LoadImageA"); ... end Claw.Low_Level_Image_Lists; with Claw.Low_Level_Image_Lists; -- Illegal! package Claw.Image_List is type Image_List_Type is tagged private; procedure Load_Image (Image_List : in out Image_List_Type; Image : in String; Monochrome : in Boolean := False); ... private type Image_List_Type is tagged record Handle : Claw.Low_Level_Image_Lists.HImage_List; Flags : Claw.Low_Level_Image_Lists.IL_Flags; ... end record; end Claw.Image_List; We ended up moving things to the private part of the parent (Claw) [which makes it very large], eliminating some of the strong typing (since users don't access this code, it only makes our job harder), and not bothering with the private packages in the first place (putting the entire contents into the private part of the Image_List package; but of course that mixes up the high-level and low-level code). ---- I haven't yet looked at the visibility ramifications of such a feature, but I will do so if there is sufficient interest in working out a full proposal. **************************************************************** From: dewar@gnat.com Sent: Wednesday, February 14, 2001 4:50 PM <> I think it has a much more significant benefit, which is that it makes it easier to separate the public and private part into separate files, where the private part has multiple implementations. We have often needed that capability, and in fact on our enhancement list for GNAT is to allow the private part to be in a separate file. **************************************************************** From: Pascal Leroy [pleroy@rational.com] Sent: Thursday, February 15, 2001 2:01 AM > A recent discussion on comp.lang.ada proposed a "with private" context > clause, which would allow the withed entity to be used only in the private > part of a package. I agree that this would be a very useful thing to have. There is another benefit, in addition to the interaction with private children: by making a with clause private, you ensure that in the course of maintenance it won't be used to write declarations in the visible part, i.e., the stuff in the withed unit won't be reexported. Moreover, it seems quite easy to (1) specify in RM terms and (2) implement. A much better usefulness/complexity ratio than extensible enums, if you ask me. **************************************************************** From: dewar@gnat.com Sent: Thursday, February 15, 2001 12:15 PM I very much agree with this asessment! **************************************************************** From: Tucker Taft Sent: Thursday, February 15, 2001 8:57 AM Randy Brukardt wrote: > > A recent discussion on comp.lang.ada proposed a "with private" context > clause, which would allow the withed entity to be used only in the private > part of a package. > > The primary benefit of such a feature is that it would allow the use of > private packages in the private part of a public package. This is currently > impossible, and it forces reorganization of packages. This is not a trivial change. Currently, private children are *never* needed at compile-time of public specs (ignoring macro expansion requirements related to generics and inlines, of course!). This allows a strong physical separation between the public specs and the "implementation" of a subsystem. I would be reluctant to see this principle violated. In fact, "private" children should more properly be called "body" children. > > For instance, originally in Claw we put the low-level Win32 interface in a > series of private packages. However, these packages cannot be accessed in > the private part of the public types. That means that either we had to avoid > strong typing in the low-level interface, or abandon the private package > structure. An alternative structure is to make these *public* packages but with essentially all of their declarations in the private part. Is there a reason why this wouldn't work? > > For instance, a possible image list package would look like: > > package Claw.Low_Level_Image_Lists is > type HImage_List is new DWord; > type IL_Flags is new UInt; > ILR_DEFAULTCOLOR : constant IL_Flags := 16#0000#; > ILR_MONOCHROME : constant IL_Flags := 16#0001#; > ... > type Image_Kind_Type is (Bitmap, Icon, Cursor); > for Image_Kind_Type use (Bitmap => 0, Icon => 1, Cursor => 2); > > function Image_List_Load_Image (Name : in Claw.Win32.LPCStr; > Width : in Claw.Int; > Image_Kind : in Image_Kind_Type; > Flags : in IL_Flags) return > HImage_List; > pragma Import (StdCall, Image_List_Load_Image, > "ImageList_LoadImageA"); > > ... > end Claw.Low_Level_Image_Lists; > > with Claw.Low_Level_Image_Lists; -- Illegal! > package Claw.Image_List is > type Image_List_Type is tagged private; > procedure Load_Image (Image_List : in out Image_List_Type; Image : in > String; > Monochrome : in Boolean := False); > ... > private > type Image_List_Type is tagged record > Handle : Claw.Low_Level_Image_Lists.HImage_List; > Flags : Claw.Low_Level_Image_Lists.IL_Flags; > ... > end record; > end Claw.Image_List; > > We ended up moving things to the private part of the parent (Claw) [which > makes it very large], eliminating some of the strong typing (since users > don't access this code, it only makes our job harder), and not bothering > with the private packages in the first place (putting the entire contents > into the private part of the Image_List package; but of course that mixes up > the high-level and low-level code). I would think public children with essentially all of their interesting decls in their private part would help break these big private parts up. > > ---- > > I haven't yet looked at the visibility ramifications of such a feature, but > I will do so if there is sufficient interest in working out a full proposal. **************************************************************** From: Pascal Leroy Sent: Thursday, February 15, 2001 9:50 AM > An alternative structure is to make these *public* packages > but with essentially all of their declarations in the private part. > Is there a reason why this wouldn't work? I don't understand this. Declarations in the private part are not visible anyway, so what good would it do? Could you give an example of what you have in mind? **************************************************************** From: Randy Brukardt [Randy@RRSoftware.Com] Sent: Thursday, February 15, 2001 11:49 AM > An alternative structure is to make these *public* packages > but with essentially all of their declarations in the private part. > Is there a reason why this wouldn't work? Sure, no one would have visibility on the declarations in the private part. How could you use them? You must have had something else in mind; could you recast my example as you suggest? **************************************************************** From: Tucker Taft Sent: Thursday, February 15, 2001 12:11 PM Pascal Leroy wrote: > > > An alternative structure is to make these *public* packages > > but with essentially all of their declarations in the private part. > > Is there a reason why this wouldn't work? > > I don't understand this. Declarations in the private part are not visible > anyway, so what good would it do? Could you give an example of what you > have in mind? Good point. I realize I was misremembering a suggestion by Robert Eachus. The "trick" is to have an immediate parent which has all of its declarations in its private part, and then use renaming to rename the child so that it is directly beneath its grandparent. For example: package Claw is ... end Claw; package Claw.Hidden is private -- lots of private junk end Claw.Hidden; package Claw.Hidden.Child is -- useful stuff private -- Claw.Hidden private part is visible here end Claw.Hidden.Child; with Claw.Hidden.Child; package Claw.Child renames Claw.Hidden.Child; Not particularly elegant, but might solve the problem. **************************************************************** From: Randy Brukardt Sent: Thursday, February 15, 2001 1:49 PM Well, Claw has 6 private low-level packages (otherwise, *they* get too large -- Win32 is huge). Would you like to try this solution for a set of interrelated private packages?? :-) :-) This is, after all, essentially what we did to work around this problem: we declared lots of stuff in the private part of the ultimate parent (Claw), but the effect is to bloat that package. It doesn't provide a solution, just a work-around. **************************************************************** From: Randy Brukardt Sent: Thursday, February 15, 2001 6:19 PM We've gotten so fixed on Tucker's silly workaround suggestion that no one has addressed his real concerns... > This is not a trivial change. Currently, private children are *never* > needed at compile-time of public specs (ignoring macro expansion > requirements related to generics and inlines, of course!). This > allows a strong physical separation between the public specs and the > "implementation" of a subsystem. I would be reluctant to see this > principle violated. > > In fact, "private" children should more properly be > called "body" children. You are forgetting that the private part of a spec really is part of the *implementation* of a unit, not part of the specification. So, the current situation is that part of the implementation can use private units, and part don't. If you really want to have this sort of physical separation, we have to have some way to put private parts in a separate file. That seems like a much more radical change than "with private" would be. Given that Robert indicated that ACT was thinking about implementing something on that line, perhaps it would be worthwhile to engage in a bit of on-the-fly language design. Here are my assumptions: 1) We don't want to change the invariant that the size of an Ada entity is known once the spec is compiled. Eliminating that would be a massive change to Ada compilers, and I really doubt that any such idea could get much support from implementors. 2) We do want to allow a separate private part have its own context clause, and allow private units to be withed there. 3) We need rules that would work both in source-based and "traditional" compiler structures. 4) We don't need any additional functionality in the private part other than (2). (1) implies that the separate private part must be available when the specification is compiled. For the "traditional" model, that means either it must be compiled first (but what could that mean? It could depend on parts of the spec) or compiled at the same time as the spec. For the "source-based" model, this means that the source must be available when the spec is compiled/used. Assuming that the private part is available when the spec is compiled, the separate private part would essentially be an "include" file, and shouldn't cost much additional work in compilers. Most of the work would go into the functionality of "with private". Syntax for this seems hard to come up with. The best I can come up with would be: package is private is separate; end ; separate () package private is end ; Clearly, we would need a rule requiring the separate private to be available when the spec is compiled -- and that is very different than other separates, which are "real" separate compilation. We also would need to extend the permissions in 10.1.4(7) to allow removing the spec from the library when the private part is "added to the environment". I guess my primary objection to this idea is that it isn't what it looks like -- the private part is not really independent of the specification. But that isn't necessarily a big deal (and different syntax might help here). Tuck, would a proposal on this line address your objection?? **************************************************************** From: Robert A Duff Sent: Thursday, February 15, 2001 8:14 PM Randy suggests: > Syntax for this seems hard to come up with. The best I can come up with > would be: > > > package is > > private is separate; > end ; > > > separate () > package private is > > end ; If I were designing the language from scratch, I would put the "imports" (with_clauses) *inside* the thing importing. And the private part would be a separate syntactic entity, presumably in a separate file. Or it wouldn't exist at all. But we're stuck with private parts. Sigh. I suggest this syntax: package is end ; package private is end ; Presumably, most compilers would require that the private part "exist" when compiling clients, and when compiling the visible part itself. No need to make it look like a subunit, IMHO. **************************************************************** From: Randy Brukardt Sent: Thursday, February 15, 2001 8:33 PM > I suggest this syntax: > > > package is > > end ; > > > package private is > > end ; > > Presumably, most compilers would require that the private part "exist" > when compiling clients, and when compiling the visible part itself. > No need to make it look like a subunit, IMHO. The problem with that is that a compiler couldn't tell the difference between a package spec that has a separate private part, and one that has no private part at all. We fixed problems like that in Ada 95, I don't think we'd want to reintroduce them. So there has to be some sort of stub in the package spec. **************************************************************** From: Pascal Leroy Sent: Friday, February 16, 2001 2:44 AM > > This is not a trivial change. Currently, private children are *never* > > needed at compile-time of public specs (ignoring macro expansion > > requirements related to generics and inlines, of course!). This > > allows a strong physical separation between the public specs and the > > "implementation" of a subsystem. I would be reluctant to see this > > principle violated. I don't see why Tuck considers this principle so important. This is really throwing the baby out with the bathwater. I have run into the problem decribed by Randy several times myself (among other things, in implementing some of the language-defined units, eg strings and I/O) and my conclusion was that private units are like limited private types, they look nice but are unusable in practice. > > In fact, "private" children should more properly be > > called "body" children. > > You are forgetting that the private part of a spec really is part of the > *implementation* of a unit, not part of the specification. So, the current > situation is that part of the implementation can use private units, and > part don't. Absolutely. This is why Tuck's principle is flawed in my opinion. > If you really want to have this sort of physical separation, we have to have > some way to put private parts in a separate file. That seems like a much > more radical change than "with private" would be. I don't like the direction that this discussion is taking. "with private" is really quite simple, and I suspect we could come up with a proposal and/or experimental implementations quickly, if we could overcome Tuck's reluctance. On the other hand, separate private parts are a much bigger change, especially for library-based compilers (I don't understand what it means for the separate private part to be "available" when compiling the spec; this doesn't make any sense for library-based compilers; if it did, we would not have trouble with mutually-dependent packages). > Given that Robert indicated that ACT was thinking about implementing > something on that line... And that's fine. First because GNAT can do what it wants in a non-standard mode (I'm told that it can even compile C code in a non-standard mode :-) and second because it's useful to do experiments on possible extensions to the language. But if we want a solution quickly (and that seems important because it is a real problem that real people are having right now) then it will have to be some form of "with private". **************************************************************** From: Ehud Lamm Sent: Friday, February 16, 2001 8:38 AM > > I don't like the direction that this discussion is taking. "with private" > is really quite simple, and I suspect we could come up with a proposal > and/or experimental implementations quickly, if we could overcome Tuck's > reluctance. I agree. It sems pretty much straightforward, and has some important benefits for readability and maintenance. As this relates to layered achitectural style, which I find to be the corner stone of abstraction, I find this esp. important. It also makes the progammers decision explicit: Does he want the unit to be visibile in the public part of the spec? Making such decisions explicit was mentioned in the steelman, and for good reasons. **************************************************************** From: Robert A Duff Sent: Friday, February 16, 2001 10:37 AM Randy says: > The problem with that is that a compiler couldn't tell the difference > between a package spec that has a separate private part, and one that has no > private part at all. We fixed problems like that in Ada 95, I don't think > we'd want to reintroduce them. We fixed one "problem" like that: optional package bodies. However, I think that was a mistake. I think there *was* no language problem. The problem was an implementation one: Ada 83 compilers ought to have checked whether an optional body exists. They didn't, and that led to the error-prone behavior. Note that GNAT originally had the *same* error-prone behavior. If an optional body existed on disk, GNAT would silently ignore it. GNAT would only give the error message if you explicitly asked it to compile the file, thus defeating the whole point of the new language rule disallowing optional bodies. My point here is not to gripe about GNAT (after all, they have long-since fixed that bug); my point is that this is an issue of how you define what's in the program library (that is, an implementation issue), and not a language issue. >... So there has to be some sort of stub in the > package spec. I don't agree. Pascal says: > I don't like the direction that this discussion is taking. "with private" > is really quite simple, and I suspect we could come up with a proposal > and/or experimental implementations quickly, if we could overcome Tuck's > reluctance. On the other hand, separate private parts are a much bigger > change, ... True. But "with private" seems aesthetically unappealing to me. >...especially for library-based compilers (I don't understand what it > means for the separate private part to be "available" when compiling the > spec; this doesn't make any sense for library-based compilers; if it did, we > would not have trouble with mutually-dependent packages). I don't see what the big deal is. Your compiler has some file-naming conventions (foo.1.ada, etc), so it seems like you could train it to look for private parts according to some convention. Or require the user to tell you where it is. But if you and Randy both say so, I suppose I must be wrong. > > Given that Robert indicated that ACT was thinking about implementing > > something on that line... > > And that's fine. First because GNAT can do what it wants in a non-standard > mode (I'm told that it can even compile C code in a non-standard mode :-) > and second because it's useful to do experiments on possible extensions to > the language. Well, the feature won't be useful to *me* unless it's implemented by more than just GNAT. > But if we want a solution quickly (and that seems important because it is a > real problem that real people are having right now) then it will have to be > some form of "with private". Perhaps you're right, but "with private" will look pretty silly if and when we have private parts in separate files, or Tuck's suggestions about putting things in the body. **************************************************************** From: Randy Brukardt Sent: Friday, February 16, 2001 10:37 PM Bob says, replying to me: > Randy says: > > > The problem with that is that a compiler couldn't tell the difference > > between a package spec that has a separate private part, and one that has no > > private part at all. We fixed problems like that in Ada 95, I don't think > > we'd want to reintroduce them. > > We fixed one "problem" like that: optional package bodies. However, I > think that was a mistake. I think there *was* no language problem. > The problem was an implementation one: Ada 83 compilers ought to have > checked whether an optional body exists. They didn't, and that led to > the error-prone behavior. In a library-based compiler, that is impossible. If the code hasn't been submitted to the compiler, it doesn't know about it. In a source-based compiler, that *might* be possible. But in any case, that wasn't the problem. The problem with Ada 83 was that if the body became obsolete, it silently disappeared from the program. Some compilers gave warnings about this; but doing anything else was incorrect. There even was an ACVC test to force this (non-friendly) behavior: Janus/Ada gave a link error until we had to "fix" it to ignore the error in that one special case just so we could validate. In our case, at least we gave a warning, because we had to write a bunch of extra code to make that ACVC test pass. The whole point of the change in Ada 95 was to get rid of that ACVC test. > >... So there has to be some sort of stub in the > > package spec. > > I don't agree. I still don't agree with you. Then Bob replies to Pascal: > Pascal says: > > > I don't like the direction that this discussion is taking. "with private" > > is really quite simple, and I suspect we could come up with a proposal > > and/or experimental implementations quickly, if we could overcome Tuck's > > reluctance. On the other hand, separate private parts are a much bigger > > change, ... > > True. But "with private" seems aesthetically unappealing to me. Can't argue with that. Which is why I suggested a brief foray into other possible solutions. > >...especially for library-based compilers (I don't understand what it > > means for the separate private part to be "available" when compiling the > > spec; this doesn't make any sense for library-based compilers; if it did, we > > would not have trouble with mutually-dependent packages). > > I don't see what the big deal is. Your compiler has some file-naming > conventions (foo.1.ada, etc), so it seems like you could train it to > look for private parts according to some convention. Or require the > user to tell you where it is. > > But if you and Randy both say so, I suppose I must be wrong. You're wrong. :-) For Janus/Ada, the compiler has no naming conventions. (The Make tool does, but that's a different issue). The only units that the compiler (and program library) knows about are those that it has been given to compile. There may be other source laying around, but it is irrelevant. To implement some sort of separate private part, we'd have to "pre-compile" it (probably just do a syntax check) to insert it into the library; then it would really be compiled when the stub was seen. Janus/Ada is syntax-based: the only time it does something is when the syntax demands it. Thus, reading the library happens only when there is a stub. I think you're also putting a terrible burden on the reader of the source if there is no indication that there is a private part missing. How would they know if an "optional" private part (just like an optional body, not required because there is nothing deferred) even exists? We don't want to design features that make Ada HARDER to maintain. Anyway, this would put a terrible new burden on the tools (especially the make tool), and I suspect it will be a non-starter for that reason alone. **************************************************************** From: Tucker Taft Sent: Friday, February 16, 2001 8:46 AM Randy Brukardt wrote: > > We've gotten so fixed on Tucker's silly workaround suggestion ... Hey, I resent that ;-). > ... that no one has addressed his real concerns... > > > This is not a trivial change. Currently, private children are *never* > > needed at compile-time of public specs (ignoring macro expansion > > requirements related to generics and inlines, of course!). This > > allows a strong physical separation between the public specs and the > > "implementation" of a subsystem. I would be reluctant to see this > > principle violated. > > > > In fact, "private" children should more properly be > > called "body" children. > > You are forgetting that the private part of a spec really is part of the > *implementation* of a unit, not part of the specification. So, the current > situation is that part of the implementation can use private units, and part > don't. I don't see it that way. When I present Ada to neophytes, I say the visible part is the "logical interface" and the private part of the spec is the "physical interface" and the body is the "implemenation." I think rather than trying to make private parts more sophisticated, we should investigate simplifying them, and pushing more stuff to the body. It is clear that in some cases, the size of a type is not known at compile-time, e.g. when the type includes a nested array component whose length is not known at compile time. This implies that compilers have no problem dealing with such types, and would seem a small step to introduce a kind of private type where the full type information is deferred to the body. (For compilers like RR where nested dynamic components are handled with a level of indirection, clearly such a private type would also involve a level of indirection.) The other thing which really wants to be deferred to a body is the full declaration for a deferred constant, so that large constant tables can be given in a body rather than in a spec. So... How about something like: type Priv(Discrim : Integer) is private; Null_Priv : constant Priv; private type Priv(Discrim : Integer) is record in body; Null_Priv : constant Priv in body; Clearly declaring an object of type Priv or using Null_Priv implies an elaboration check that the corresponding full declaration in the body has been elaborated. Something like this additional elaboration check will be needed in any case if we postpone elaboration of the entire private part. Of course only composite types could have their full declaration postponed into the body. Otherwise pass by copy could be truly nasty. > ... > Tuck, would a proposal on this line address your objection?? Not really. I prefer something more along the lines above, where individual declarations can have their full definitions deferred into the body. **************************************************************** From: Robert A Duff [bobduff@world.std.com] Sent: Friday, February 16, 2001 4:46 PM > I don't see it that way. When I present Ada to neophytes, I say > the visible part is the "logical interface" and the > private part of the spec is the "physical interface" and > the body is the "implemenation." I think that view of private parts is rather unusual. I find it strange to call the private part an "interface". Do you consider a procedure body to be a "physical interface" in the case where it is inlined? It's just like a private part, in the sense that the compiler looks at it in order to generate (presumably better) code. The explanation I've heard many times (and agree with) is that the private part contains stuff that logically belongs in the body, but for efficiency, we want the compiler to be able to see it (when compiling clients). In other words, it's an efficiency hack. Calling it an "interface" of some sort seems to raise it to a higher level. (In case you can't tell: If I were designing a language from scratch, it would not have private parts. It would have package specs defining the interface (and only the interface), and package bodies defining the implementation. And in fact, I'm *always* designing a language, in my head. It's my hobby. ;-)) > I think rather than trying to make private parts more sophisticated, > we should investigate simplifying them, and pushing more stuff > to the body. This sounds like an excellent plan. Should have happened 20 years ago. ;-) However, such a feature would be incomplete without a new pragma analogous to Inline. This new pragma would tell the compiler to look at the body of a with-ed package, and generate code that depends on the full type and full constant declarations it finds there (eg, know the size of a record at compile time, if possible). This is what pragma Inline does for procedures: look at the package body, and depend on the contents of the procedure body it finds there. The effect on dependences and compilation order and whatnot for this new pragma would be as for pragma Inline (and these effects depend on the library model of that compiler). If you use this pragma, you should get code (in client packages) identical to what you get now, when you put the full type in the private part, so the compiler can look at it. This new pragma seems important to me: If you don't have it, you're stuck with an annoying choice between efficiency at run time, versus the benefits of putting the thing in the body: efficiency of compile time, ability to "with" private children, better management of source-file variants. Furthermore, if you put something in the body, and you later decide that's too inefficient, you don't want to move it to the private part, because that wrecks the structure of your program -- you might have to rearrange all your packages, make private packages public, etc. Much better to slap a pragma on it. Just like it's much better to use pragma Inline than to hand-inline the code of that procedure. > It is clear that in some cases, the size of a type > is not known at compile-time, e.g. when the type includes a nested > array component whose length is not known at compile time. This > implies that compilers have no problem dealing with such types, > and would seem a small step to introduce a kind of private > type where the full type information is deferred to the body. > (For compilers like RR where nested dynamic components are handled > with a level of indirection, clearly such a private type would also > involve a level of indirection.) > > The other thing which really wants to be deferred to a body > is the full declaration for a deferred constant, so that large constant > tables can be given in a body rather than in a spec. > > So... > > How about something like: > > type Priv(Discrim : Integer) is private; > Null_Priv : constant Priv; > > private > > type Priv(Discrim : Integer) is record in body; Why "record"? Does the compiler need to know it's a record? Is it allowed to be an array, task, protected? > Null_Priv : constant Priv in body; > > Clearly declaring an object of type Priv or using Null_Priv implies > an elaboration check that the corresponding full declaration in the > body has been elaborated. Something like this additional elaboration > check will be needed in any case if we postpone elaboration of > the entire private part. No, no, no! The proposal to split out the private part into a separate syntactic entity, presumably in a separate source file, should *not* change the run-time semantics in the slightest. The private part should still be elaborated immediately after the visible part. > Of course only composite types could have their full declaration > postponed into the body. Otherwise pass by copy could be > truly nasty. Sigh. > > ... > > Tuck, would a proposal on this line address your objection?? > > Not really. I prefer something more along the lines above, where > individual declarations can have their full definitions deferred > into the body. I also prefer something along the lines of the above, but I still don't understand Tuck's desire to preserve some sort of "physical interface". If we have to have private parts, I don't see why they can't see private children. But I agree with Tuck that moving information from private parts to bodies is the right idea. **************************************************************** From: Michael Yoder Sent: Friday, February 16, 2001 7:01 PM On this issue I agree with Pascal and Ehud. But let me start by quoting Bob quoting Tucker: > > I think rather than trying to make private parts more sophisticated, > > we should investigate simplifying them, and pushing more stuff > > to the body. > >This sounds like an excellent plan. Should have happened 20 years ago. >;-) [discussion of how Bob's ideal language would work snipped] I'm skeptical we had the knowledge needed to do this right 20 years ago. I'm skeptical we know *today* how to do it right. (Yes, it is possible if code generation is always done at what we call "link time.") But be that as it may, "with private" is preferable unless we can finish all of Tucker's investigations in the reasonably near future. "With private" cuts the Gordian knot and Tucker is advocating teasing it apart. It would be better to do "with private" and then move towards a Duffian or Taftian ideal language; if we arrive, "with private" and private parts can then be made deprecated features. I've often wanted to insert a second context clause right after the keyword 'private' in a package specification; each time my workaround was to promote stuff I wanted in private packages into a public "wannabe private" package. > > > ... > > > Tuck, would a proposal on this line address your objection?? > > > > Not really. I prefer something more along the lines above, where > > individual declarations can have their full definitions deferred > > into the body. > >I also prefer something along the lines of the above, but I still don't >understand Tuck's desire to preserve some sort of "physical interface". >If we have to have private parts, I don't see why they can't see private >children. But I agree with Tuck that moving information from private >parts to bodies is the right idea. I also prefer this, but I'd like to have "with private" in the interim until I get all of it. **************************************************************** From: Randy Brukardt Sent: Friday, February 16, 2001 10:47 PM Tucker said: (Discussion of unusual world-view deleted :-) > I think rather than trying to make private parts more sophisticated, > we should investigate simplifying them, and pushing more stuff > to the body. ... > How about something like: > > type Priv(Discrim : Integer) is private; > Null_Priv : constant Priv; > > private > > type Priv(Discrim : Integer) is record in body; > Null_Priv : constant Priv in body; > >Clearly declaring an object of type Priv or using Null_Priv implies >an elaboration check that the corresponding full declaration in the >body has been elaborated. Something like this additional elaboration >check will be needed in any case if we postpone elaboration of >the entire private part. I wouldn't be adverse to working on this idea further. It seems to just be syntactic sugar for: type Priv(Discrim : Integer) is private; Null_Priv : constant Priv; private type (Discrim : Integer); -- Deferred to body. type Priv(Discrim : Integer) is access (Discrim); Null_Priv : constant Priv in body := ; The only new thing about this would be the handling of the discriminants. However, I think that the real-time and safety-critical people wouldn't be happy: the last thing they want is more dynamic allocation of memory. They'd probably never use this feature, and thus we'd still need "with private". (I think Bob's pragma Inline for these is unworkable, since it couldn't be implemented with link-time inlining; and thus would require library dependencies that I simply will not stand for.) **************************************************************** From: Robert A Duff Sent: Saturday, February 17, 2001 9:43 AM > I wouldn't be adverse to working on this idea further. It seems to just be > syntactic sugar for: > > type Priv(Discrim : Integer) is private; > Null_Priv : constant Priv; > > private > > type (Discrim : Integer); -- Deferred to body. > type Priv(Discrim : Integer) is access (Discrim); > Null_Priv : constant Priv in body := ; > > The only new thing about this would be the handling of the discriminants. No, I don't think it's quite that simple. For Tucker's idea, you want the compiler to manage the storage. For the incomplete type deferred to the body (which was a younger Tucker's idea, by the way!), you have an explicit access type, so the programmer is required to manage the storage (which is why I never use that feature unless I wanted a pointer type anyway). > However, I think that the real-time and safety-critical people wouldn't be > happy: the last thing they want is more dynamic allocation of memory. They'd > probably never use this feature, and thus we'd still need "with private". It's no more dynamic than an array of run-time-known size. That is, it's not necessary to use the heap. (If some compilers choose to use the heap, that's fine, but we should preserve the feasibility of never using the heap except for explicit access types). > (I think Bob's pragma Inline for these is unworkable, since it couldn't be > implemented with link-time inlining; and thus would require library > dependencies that I simply will not stand for.) If some compilers can't implement the new pragma Inline, that's OK. But I think it's extremely important to standardize the pragma, so those compilers that care about this issue can support it (portably!). Most compilers would in fact have no trouble implementing it. **************************************************************** From: Randy Brukardt Sent: Monday, February 19, 2001 4:16 PM > No, I don't think it's quite that simple. For Tucker's idea, you want > the compiler to manage the storage. For the incomplete type deferred to > the body (which was a younger Tucker's idea, by the way!), you have an > explicit access type, so the programmer is required to manage the > storage (which is why I never use that feature unless I wanted a pointer > type anyway). I meant that to be implied. I should have added a Storage_Pool clause to indicate that. I was mainly concerned about the code generation, which is the same as above with an appropriate initialization New at each declaration. Alternatively, I could have wrapped the access in a controlled type to do that. Still, there is nothing new here... > It's no more dynamic than an array of run-time-known size. That is, > it's not necessary to use the heap. (If some compilers choose to use > the heap, that's fine, but we should preserve the feasibility of never > using the heap except for explicit access types). I wasn't talking about the heap per-se. I don't think that the Safety-critical people use dynamic arrays, either. That's because they don't want non-deterministic memory usage. I stand by my comment. **************************************************************** From: Pascal Leroy Sent: Saturday, February 17, 2001 5:01 AM Bob (who is always designing languages) explained: > I think that view of private parts is rather unusual. I find it strange > to call the private part an "interface". > > The explanation I've heard many times (and agree with) is that the > private part contains stuff that logically belongs in the body, but for > efficiency, we want the compiler to be able to see it (when compiling > clients). In other words, it's an efficiency hack. Calling it an > "interface" of some sort seems to raise it to a higher level. I completely agree with this view. The notion that something which is invisible to clients is an "interface" doesn't make sense to me. Tuck proposed: > > I think rather than trying to make private parts more sophisticated, > > we should investigate simplifying them, and pushing more stuff > > to the body. I can agree with this, although as Bob pointed out we would want a pragma of some sort (heck, it could be Inline applied to a type) to force the compiler to generate decent code. However, I believe we need to be pragmatic here. Pushing more stuff to the body is probably sensible, but it is going to take several years to refine/understand the consequences of this new model. On the other hand, let me say it once more, "with private" could work tomorrow (tomorrow in ARG terms probably means next year, I'm sure we all realize that). Also, we have to keep in mind that there is a lot of code out there that uses private parts, and restructuring that code to use the "in body" clause might be a lot of work. On the other hand, adding "private" to a couple of with clauses is an extremely cheap change. So I guess I am saying that I like Mike Y's proposal: > It would be better to do "with private" and then move towards a > Duffian or Taftian ideal language; if we arrive, "with private" and private > parts can then be made deprecated features. **************************************************************** From: Robert A Duff Sent: Saturday, February 17, 2001 9:37 AM > I can agree with this, although as Bob pointed out we would want a pragma of > some sort (heck, it could be Inline applied to a type) to force the compiler > to generate decent code. I almost suggested extending pragma Inline. Of course it doesn't "force" anything -- it's your customers with open checkbooks that do the forcing. ;-) > So I guess I am saying that I like Mike Y's proposal: > > > It would be better to do "with private" and then move towards a > > Duffian or Taftian ideal language; if we arrive, "with private" and private > > parts can then be made deprecated features. Sounds reasonable to me. **************************************************************** From: Tucker Taft Sent: Saturday, February 17, 2001 1:53 PM > I almost suggested extending pragma Inline. I think this somewhat defeats the purpose of the "in body." I see the "in body" as allowing more dynamically constructed systems. Pragma inline goes just the opposite, increasing the amount of statically bound decisions. I also don't see why this is expected to be so inefficient, given how often one ends up with a dynamically-sized type already. Perhaps the idea is that while the system is being developed, the dynamic approach is great, but once you want to deliver the most heavily optimized version, you can "inline" things. I can't imagine going to the bother of using "in body" if you "inline" right away. **************************************************************** From: Robert A Duff Sent: Saturday, February 17, 2001 9:53 AM Randy says: > In our case, at least we gave a warning... Well, if you can give a warning, I don't see why you can't just as easily give an error. The implementation I'm imagining for a library-based compiler is that the compiler has a rule that if there's a private part, you have to submit it to the compiler at the same time as you submit the visible part. Eg, if there's a command-line interface, you would type in two file names. If you don't, and the private part turns out to exist at link time, then complain. But I'm not dead-set against having a stub-like syntax. > I think you're also putting a terrible burden on the reader of the source if > there is no indication that there is a private part missing. I find that argument somewhat convincing. But not entirely. When I want to know if a package body exists, I go and look at its file. If that file doesn't exist, then the package body doesn't exist. (I'm presumable either using some file-naming conventions voluntarily, or else my compiler forces me to.) I certainly don't carefully read the spec, to see if a body is required. You also can't tell from a package spec whether any children exist. So the private part doesn't seem like that big of a deal. To tell whether it exists, go look for it in the directory where you keep your source code. **************************************************************** From: Pascal Leroy Sent: Sunday, February 18, 2001 4:26 AM So the model you have in mind is merely a #include, right? Fine, but that's outside of the language in my opinion. I don't believe you can phrase the above discussion in RM terms, i.e. "entered in the environment." **************************************************************** From: dewar@gnat.com Sent: Sunday, February 18, 2001 7:56 AM <> I strongly disagree, suppose you had the following: a spec p a body p where the body was not required Now you build a program with the spec and body, and everything works fine. Now you edit the spec, and you recompile the spec, the body simply gets left out. What do you mean "check whether an optional body exists", you cannot check if an optional body exists in the normal case, without searching the universe. Yes, you can warn if one happens to be around, and you can warn that one used to exist. But you MUST be allowed (in Ada 83) to rebuild the executable with only the new spec, and not the new body. The compiler cannot prevent you from constructing this modified program, since it is legal. The point in Ada 95 was to remove the requirement of being able to construct the "wrong" program. Since every Ada 83 compiler had to support this capability, and the capability itself is what was fundamentally flawed, I think the change to Ada 95 was highly desirable. <> That's completely confused, yes, that's a problem, one that might exist in any compiler, but it has nothing whatsoever to do with the problem we are talking about, and which this language solution exists. The new Ada 95 feature is NOT talking about issues in building programs in the first place, it is talking about the error prone behavior where you modify a spec that does not require a body, and the modification does not force a recompilation of the body. It is *ENTIRELY* that modification scenario, required to "work" in all Ada 83 compilers that the new Ada 95 feature is addressing. What Bob Duff is referring wrt GNAT is that when you build a program in the first place, where you have an improper body, then it is nice if the automatic compilation tools make the effort to see if a body is around (what on earth that means is of course very compilation environment dependent). The "new" GNAT here searches everywhere on the path for something that might be a body, and makes you get rid of it. That's not always the right thing to do, but it is safer, but this error check has nothing at all to do with the language feature. I am a bit surprised at this confusion, because this was a well known problem in Ada 83, that was completely eliminated in Ada 95, in all Ada 95 compilers, and in all versions of GNAT, and was a welcome change in Ada 95. Indeed if we have separated private parts, it is absolutely essential in my view that we not repeat the mistake that Ada 83 made in this area. Yes, you can defend against it to some limited extent by the kind of peculiar searching around for possible peculiarities that GNAT does, but that is not a desirable behavior. Note incidentally that the RM appears to prohibit the GNAT behavior, because there are specific rules about new units obsoleting old ones. What we do for the ACVC runs is to use a crackpot (i.e. ACVC only) script that sees GNAT issue the message of an unwelcome body or spec, and then deletes it and transparently reattempts the compilation. In other words, the following sequence must work as far as the ACVC tests are concerned. Introduce p.ads (spec needing body) and p.adb (body) into compilation environment, and compile Introduce new p.ads (spec not needing body) into compilation environment and compile. GNAT will reject the second attempt, but the ACVC test won't tolerate that rejection, so we simply automatically delete the p.adb and proceed (of course you would never want to do that automatically in real life, which is why I call this a crackpot script). **************************************************************** From: Tucker Taft Sent: Saturday, February 17, 2001 1:47 PM Pascal Leroy wrote: > ... > However, I believe we need to be pragmatic here. Pushing more stuff to the > body is probably sensible, but it is going to take several years to > refine/understand the consequences of this new model. On the other hand, > let me say it once more, "with private" could work tomorrow (tomorrow in ARG > terms probably means next year, I'm sure we all realize that). I don't think this is a good argument. I really don't want to add something and then soon thereafter declare it obsolescent. On the other hand, I do see some value in "with private" though I hate the name, since it brings up bad memories of an Ada 9X proposal of the same name. Maybe "private with"? We aren't "with"ing the private part, but rather "privately" withing the visible part, so I think "private with" might make more sense anyway, although it may be a bit trickier to parse. I also don't think we should ignore the possibility of moving the "with" clauses to immediately after the word "private". I personally think we should drop discussion of physically separating the "private" part, and leave that to compilers to do if they so choose, especially if it is supposed to be completely semantically neutral. But getting back to "private with" -- exactly what was the proposal? I have lost it in all the other discussion. Clearly we can't allow a parent package spec to "with" its own private children. So instead it must be siblings, nieces, etc. that can "private with" their private siblings, aunts, etc. I suppose an alternative is to simply allow these "with" clauses, but then say that if the with'ed unit is private, it only becomes visible in the private part. This is roughly equivalent to saying that when a unit is "with"ed, if it is a private child, it is implicitly inserted at the end of the private part of its parent, while if it is a public child, it is implicitly inserted at the end of the visible part of its parent. In any case, a spec can never "with" its own descendant. > ... > So I guess I am saying that I like Mike Y's proposal: > > > It would be better to do "with private" and then move towards a > > Duffian or Taftian ideal language; if we arrive, "with private" and private > > parts can then be made deprecated features. I really don't like this way of thinking. We should be convinced that "private with" is useful indefinitely, rather than putting it in as a stop-gap. I see "private with" as serving a different purpose than the "in body" stuff. It focuses on information hiding and modularization, whereas the "in body" really opens up the possibility for more dynamically constructed systems (similar to the "with type" stuff). **************************************************************** From: dewar@gnat.com Sent: Sunday, February 18, 2001 9:13 AM <> This viewpoint seems exactly right in Ada 83, but surely is completely wrong in Ada 95. The introduction of child packages that can see the private part now means that indeed it is used as an interface for the implementation, and I see Ada 95 code all the time where private parts are full of subprogram specs that would never have fit the Ada 83 model. So I don't think you can turn back the clock at this stage, the nature of private parts of packages has radically changed from the above quoted viewpoint. **************************************************************** From: Ehud Lamm Sent: Monday, February 19, 2001 1:47 AM Indeed. This is one prime reason to think that private parts as they are now are problematic. They serve two very distinct semantic functions: to declare implementation details that (per Ada-83) must be in the spec and to declare the extension interface (similar to "protected" in C++). I find the connection between child units and inheritance very elegant (see Tucker Taft's LSN on this). However, outsiders (i.e., students) have a hard time with this. Almost no one sees how to use the private part for extension purposes unless told about this specifically. I tried giving this as a riddle this semester ("Why does a pacakge have procedures declared in the private part etc. etc.") and only one student thought about child units. However, I agree with Robert: We are too far into the game to change the rules. Notice that since the above means that the private part is indeed an "interface" (that can be used only by children), it makes more sense to have it _inside the spec_ and not in a seperate file. It is not just a hack for storing impl. details: it is part of the abstraction. This is esp. true when the essence of the package is to allow extension (e.g, when it declares abstract tagged types; or in the future when it declares interfaces). **************************************************************** From: Tucker Taft [stt@avercom.net] Sent: Saturday, February 17, 2001 3:36 PM Pascal Leroy wrote: > Bob (who is always designing languages) explained: > > > I think that view of private parts is rather unusual. I find it strange > > to call the private part an "interface". > > > > The explanation I've heard many times (and agree with) is that the > > private part contains stuff that logically belongs in the body, but for > > efficiency, we want the compiler to be able to see it (when compiling > > clients). In other words, it's an efficiency hack. Calling it an > > "interface" of some sort seems to raise it to a higher level. > > I completely agree with this view. The notion that something which is > invisible to clients is an "interface" doesn't make sense to me. Well, I won't belabor the point, but it is clearly an "interface" from the compiler's point of view, and even from the programmer's point of view, 'size is visible, as are various other properties revealed only in the private part such as by-reference, atomic, volatile, etc. I call it the "physical" interface in analogy with the layers in a network protocol. It is like the "physical link" level while the visible part is more like the "application" level. Conceivably you could put the code for the body of a procedure in some other computer, but to communicate with it, you would need to know at least something about the physical representation of the data you pass to it. **************************************************************** From: Ted Baker Sent: Sunday, February 18, 2001 11:57 AM > I think that view of private parts is rather unusual. I find it strange > to call the private part an "interface". > > The explanation I've heard many times (and agree with) is that the > private part contains stuff that logically belongs in the body, but for > efficiency, we want the compiler to be able to see it (when compiling > clients). In other words, it's an efficiency hack. Calling it an > "interface" of some sort seems to raise it to a higher level. The reason we want the compiler to be able to see it is that it provides information that is NEEDED to implement the interface-- i.e., the lower-level details of the interface. I realize that some people would like to move toward a more dynamic, world, where no data representation details would need to be bound by the interface. However, there will always remain situations (e.g., interfacing to hardware and to code in other languages, and -- dare I ever hope? -- interfacing to code compiled with a different Ada compiler) where data representation will necessarily be a logical part of the interface to a software component. **************************************************************** From: dewar@gnat.com Sent: Sunday, February 18, 2001 12:26 AM <> No one is suggesting that this be part of the definition, just that it would be nice if whatever solution is decided here made it easier for compilers to do this ... **************************************************************** From: Pascal Leroy Sent: Sunday, February 18, 2001 4:22 AM > On the other hand, I do see some value in "with private" though > I hate the name, since it brings up bad memories of an Ada 9X > proposal of the same name. Maybe "private with"? Ok, I changed the subject line of this message :-) > We aren't > "with"ing the private part, but rather "privately" withing the visible > part, so I think "private with" might make more sense anyway, > although it may be a bit trickier to parse. I am not going to fight on the syntax, as long as the grammar remains reasonably unambiguous. > I also don't think we should ignore the possibility of moving the > "with" clauses to immediately after the word "private". I don't like that. It's good for readability to have the with clauses at the beginning of the unit, it summarizes the dependencies of the unit, eg in terms of compilation ordering. In fact, I believe that a number of "make" tools out there work by scanning the beginning of the unit for withs and separate. Now they would have to go much farther. Also, it seems that you would have some trouble distinguishing pragmas that appear in declarative parts from pragmas that appear in context clauses. > I personally think we should drop discussion of physically separating > the "private" part, and leave that to compilers to do if they > so choose, especially if it is supposed to be completely > semantically neutral. I couldn't agree more. > I suppose an alternative is to simply allow these "with" clauses, > but then say that if the with'ed unit is private, it only becomes > visible in the private part. No, that's not sufficient. I believe you also want to "private with" public units, but make it explicit that they are only needed for the private part. That's useful for documentation and maintenance purposes. And maybe these units will later turn into private units, but you don't want to do the required restructuring right now. Again, think of all the code out there that withs units for the sole purpose of writing a private part. **************************************************************** From: Ehud Lamm Sent: Sunday, February 18, 2001 8:57 AM > > On the other hand, I do see some value in "with private" though > > I hate the name, since it brings up bad memories of an Ada 9X > > proposal of the same name. Maybe "private with"? > > Ok, I changed the subject line of this message :-) I wouldn't fight over this... To my (non native) ears the first wording sounds better. > > > I also don't think we should ignore the possibility of moving the > > "with" clauses to immediately after the word "private". > > I don't like that. It's good for readability to have the with clauses at > the beginning of the unit, it summarizes the dependencies of the unit, eg in > terms of compilation ordering. In fact, I believe that a number of "make" > tools out there work by scanning the beginning of the unit for withs and > separate. Now they would have to go much farther. I agree with Pascal. If/when the private part goes into a seperate file, the with clauses might well follow, but as long as it remains in the spec, I think the with clauses should stay where they are. Changing this can introduce work and bugs to automatic tools, and is also bad for readability. I think that it is again a situation of better being the enemy of good enough. Unless the private part is eliminated, it is visible in the spec, so why should we work hard to move the with clauses down a few lines? > > I personally think we should drop discussion of physically separating > > the "private" part, and leave that to compilers to do if they > > so choose, especially if it is supposed to be completely > > semantically neutral. Quite. And this is why I agree that the with's should stay where they are, for the time being. **************************************************************** From: dewar@gnat.com Sent: Monday, February 19, 2001 1:05 PM <> Note that the mere fact of the with's being at the top of the abstract representation does not mean they have to be there in the physical representation if you separate this into two separate files. There is no rule that says that the only allowable way to split into two files is to draw a line in the source :-) **************************************************************** From: dewar@gnat.com Sent: Sunday, February 18, 2001 8:49 AM <> Note that it is possible to implement this right now without any change to the language (we investigated this possibility some time ago). All you need is a pragma with x; pragma Private_Only (x); that says that the unit x can only be referenced in the private part. Now you can allow the private part to be in a separate file, with the WITH clauses in that file (and no junk pragma), and you just declare that this is a representation of the text where the WITH goes where it belongs with the pragma. But it is nicer if something like this is at least semi-standardized :-) **************************************************************** From: Randy Brukardt Sent: Monday, February 19, 2001 4:47 PM No, this doesn't solve the problem. The problem is that it is illegal to with a private package in a public specification. No pragma can change that (unless of course you're in "extensions" mode). Thus we need a real extension to allow such withing; the rest of it is nice-to-have, but seems to come along for free. **************************************************************** From: dewar@gnat.com Sent: Monday, February 19, 2001 5:00 PM Sure, I understand this, but in my view this is the nice-to-have feature, the really essential one is to conveniently enable separated private parts. For example, we often find that the copyright on the private part is completely different from the copyright on the public part, and it would really be nice to have two documents (e.g. this happens with the RM defined library). **************************************************************** From: Randy Brukardt Sent: Monday, February 19, 2001 5:26 PM Humm. The problem outlined on C.L.A., and which I described, and which we're trying to solve in AI-262 is the private package needed by the private part problem. Separated private parts only came up as a possible solution to this problem. In my opinion, they are a nice-to-have, while the private package problem contorts designs (and essentially makes private packages useless for their intended purpose); thus it has a much higher priority in my view. **************************************************************** From: Randy Brukardt [Randy@RRSoftware.Com] Sent: Monday, February 19, 2001 4:39 PM > But getting back to "private with" -- exactly what was the proposal? > I have lost it in all the other discussion. I never worked out the exact details; I asked whether it was worth doing so, and the rest is history... (and a very large appendix in AI-262, and a new record in messages on Ada-Comment since I took it over). **************************************************************** From: Christoph Grein [christoph.grein@eurocopter.de] Sent: Monday, February 19, 2001 2:30 AM To: ada-comment@ada-auth.org Subject: Re: [Ada-Comment] Possible amendment: with private > But getting back to "private with" -- exactly what was the proposal? > I have lost it in all the other discussion. package S is -- Note: not private, not in hierarchy T ... end S; ----------------------- package T is ... end T; ----------------------- private package T.Pr is ... private ... end T.Pr; ----------------------- private with T.Pr, S; pacakge T.C is -- T.Pr, S invisible here private -- visible parts of T.Pr, S visible here end T.C; ------------------------------------------------------------------ I'm not sure about the following: private package X is -- Note: no visible parent (except of course Standard). ... -- Does such a package currently, private -- i.e. without the proposed amendment, ... -- have any use? end X; ----------------------- private with X; -- should this be allowed? package Y is -- Note: no hierarchical relation between X and Y -- X invisible here private -- visible part of X visible here end Y; **************************************************************** From: Michael Yoder Sent: Monday, February 19, 2001 4:20 PM Tucker you wrote: >Pascal Leroy wrote: > > ... > > However, I believe we need to be pragmatic here. Pushing more stuff to the > > body is probably sensible, but it is going to take several years to > > refine/understand the consequences of this new model. On the other hand, > > let me say it once more, "with private" could work tomorrow (tomorrow > in ARG > > terms probably means next year, I'm sure we all realize that). > >I don't think this is a good argument. I really don't want to >add something and then soon thereafter declare it obsolescent. I absolutely agree. But I am nervous about this judgment unless we agree on what "soon" means, and have strong confidence that we *can* declare it obsolescent soon. > > ... > > So I guess I am saying that I like Mike Y's proposal: > > > > > It would be better to do "with private" and then move towards a > > > Duffian or Taftian ideal language; if we arrive, "with private" and private > > > parts can then be made deprecated features. > >I really don't like this way of thinking. We should be convinced >that "private with" is useful indefinitely, rather than putting >it in as a stop-gap. > >I see "private with" as serving a different purpose than >the "in body" stuff. It focuses on information hiding and >modularization, whereas the "in body" really opens up the >possibility for more dynamically constructed systems (similar to >the "with type" stuff). Well, I may have misjudged by imagining that you and Bob were aiming at nearly identical endpoints. I think that in Bob's ideal endpoint it would become obsolete. I'm no longer sure about yours. If not, it would never become a deprecated feature unless Bob converted you. :-) ****************************************************************