* Question about record rep spec placement @ 1997-01-15 0:00 Ken Garlington 1997-01-15 0:00 ` Norman H. Cohen ` (3 more replies) 0 siblings, 4 replies; 23+ messages in thread From: Ken Garlington @ 1997-01-15 0:00 UTC (permalink / raw) We have some Ada83 code that looks like the following: package Some_Package is type Some_Record is record -- components here end record; -- some arbitrary declarations here private for Some_Record use record -- component rep spec here end record; end; Are there cases in Ada where a record representation specification cannot be deferred until the private part of the package? I'm told that when this code was compiled with an Ada 95 compiler, that the record rep spec had to be moved to immediately after the record declaration for the code to compile correctly. I'm wondering if this is (a) illegal Ada83 code that our Ada83 compiler accepted anyway (much like the use of unchecked_conversion on the left-hand side of an assignment statement, as described in another thread), (b) legal Ada code that the other Ada compiler rejected anyway, or (c) OUCH! Ada83 code that is no longer valid Ada. -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 Question about record rep spec placement Ken Garlington @ 1997-01-15 0:00 ` Norman H. Cohen 1997-01-16 0:00 ` Ken Garlington 1997-01-15 0:00 ` Bob Gilbert ` (2 subsequent siblings) 3 siblings, 1 reply; 23+ messages in thread From: Norman H. Cohen @ 1997-01-15 0:00 UTC (permalink / raw) Ken Garlington wrote: > > We have some Ada83 code that looks like the following: > > package Some_Package is > > type Some_Record is record > -- components here > end record; > > -- some arbitrary declarations here > > private > > for Some_Record use record > -- component rep spec here > end record; > > end; > > Are there cases in Ada where a record representation specification > cannot be deferred until the private part of the package? I'm told that > when this code was compiled with an Ada 95 compiler, that the record > rep spec had to be moved to immediately after the record declaration > for the code to compile correctly. I'm wondering if this is > > (a) illegal Ada83 code that our Ada83 compiler accepted anyway > (much like the use of unchecked_conversion on the left-hand side > of an assignment statement, as described in another thread), > > (b) legal Ada code that the other Ada compiler rejected anyway, or > > (c) OUCH! Ada83 code that is no longer valid Ada. The answer lies in those "arbitrary declarations". If those declarations contain what is called a "forcing occurrence" in Ada 83, such as a declaration of an object of type Some_Record, the record representation clause is illegal. Essentially the same rules hold in Ada 95, but with different terminology: The Ada-95 RM describes the object declaration or whatever as "freezing" the representation of the record type. There are a few cases where the freezing rules make a legal Ada-83 program into an illegal Ada-95 program, but these cases are obscure and pathological. For example, because of poor wording in the Ada-83 definition of "forcing occurrence", subtype S is Integer range 0 .. Some_Record'Size; was not a forcing occurrence in Ada 83, but this declaration does freeze the representation of Some_Record in Ada 95. -- Norman H. Cohen mailto:ncohen@watson.ibm.com http://www.research.ibm.com/people/n/ncohen ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 ` Norman H. Cohen @ 1997-01-16 0:00 ` Ken Garlington 1997-01-17 0:00 ` Robert A Duff 0 siblings, 1 reply; 23+ messages in thread From: Ken Garlington @ 1997-01-16 0:00 UTC (permalink / raw) Cc: George.F.Rice Norman H. Cohen wrote: > > Ken Garlington wrote: > > > > We have some Ada83 code that looks like the following: > > > > package Some_Package is > > > > type Some_Record is record > > -- components here > > end record; > > > > -- some arbitrary declarations here > > > > private > > > > for Some_Record use record > > -- component rep spec here > > end record; > > > > end; > > > > Are there cases in Ada where a record representation specification > > cannot be deferred until the private part of the package? [snip] > > There are a few cases where the freezing rules make a legal Ada-83 > program into an illegal Ada-95 program, but these cases are obscure and > pathological. For example, because of poor wording in the Ada-83 > definition of "forcing occurrence", > > subtype S is Integer range 0 .. Some_Record'Size; > > was not a forcing occurrence in Ada 83, but this declaration does freeze > the representation of Some_Record in Ada 95. We will check to see if this is the case. Is there a complete list of cases related to freezing occurences that are different between Ada83 and Ada? > > -- > Norman H. Cohen > mailto:ncohen@watson.ibm.com > http://www.research.ibm.com/people/n/ncohen -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-16 0:00 ` Ken Garlington @ 1997-01-17 0:00 ` Robert A Duff 1997-01-18 0:00 ` Ken Garlington 0 siblings, 1 reply; 23+ messages in thread From: Robert A Duff @ 1997-01-17 0:00 UTC (permalink / raw) In article <32DE3FAD.17A1@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> wrote: >We will check to see if this is the case. Is there a complete list of >cases >related to freezing occurences that are different between Ada83 and Ada? Incompatibilities are documented in the AARM. Look at section 13.14, for lots of verbiage about forcing/freezing. However, I should warn you that the Ada 83 rules did not make perfect sense to me when I wrote the AARM stuff, so the AARM list of differences is probably incomplete. How can you make a list of differences between two sets of rules, when you can't quite understand one set of rules? Note that the Ada 83 rules officially include the AI's. In any case, I'm pretty sure that the upward incompatibilities exist only for extremely obscure cases. Why don't you post your code (or a boiled-down version of it)? Any decent compiler will tell you which freezing occurrence is causing the trouble, so it shouldn't be hard to track this down. I will be surprised if you've run into an upward incompatibility -- most likely one or the other compiler has a bug. - Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Robert A Duff @ 1997-01-18 0:00 ` Ken Garlington 0 siblings, 0 replies; 23+ messages in thread From: Ken Garlington @ 1997-01-18 0:00 UTC (permalink / raw) Robert A Duff wrote: > > In article <32DE3FAD.17A1@lmtas.lmco.com>, > Ken Garlington <GarlingtonKE@lmtas.lmco.com> wrote: > >We will check to see if this is the case. Is there a complete list of > >cases > >related to freezing occurences that are different between Ada83 and Ada? > > Incompatibilities are documented in the AARM. Look at section 13.14, > for lots of verbiage about forcing/freezing. > > However, I should warn you that the Ada 83 rules did not make perfect > sense to me when I wrote the AARM stuff, so the AARM list of differences > is probably incomplete. How can you make a list of differences between > two sets of rules, when you can't quite understand one set of rules? > Note that the Ada 83 rules officially include the AI's. > > In any case, I'm pretty sure that the upward incompatibilities exist > only for extremely obscure cases. Why don't you post your code (or a > boiled-down version of it)? Any decent compiler will tell you which > freezing occurrence is causing the trouble, so it shouldn't be hard to > track this down. I will be surprised if you've run into an upward > incompatibility -- most likely one or the other compiler has a bug. Unfortunately, a different group is using our Ada83 code with their Ada compiler, and the only information I have is that they had to move rep specs out of the private part of the package to get them to compile. They originally reported this to me as a bug in our Ada83 code/compiler, which confused me, and so I posted the question that started this thread. I have forwarded the information you and others have posted here, and they are going to look at the intervening statements to see if they can see what is happening. If I get more information, I will post it. > > - Bob -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 Question about record rep spec placement Ken Garlington 1997-01-15 0:00 ` Norman H. Cohen @ 1997-01-15 0:00 ` Bob Gilbert 1997-01-16 0:00 ` Fergus Henderson 1997-01-17 0:00 ` Ken Garlington 1997-01-16 0:00 ` Jeff Creem 1997-01-16 0:00 ` Jerome Desquilbet 3 siblings, 2 replies; 23+ messages in thread From: Bob Gilbert @ 1997-01-15 0:00 UTC (permalink / raw) In article <32DCFDAA.2656@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> writes: > We have some Ada83 code that looks like the following: > > package Some_Package is > > type Some_Record is record > -- components here > end record; > > -- some arbitrary declarations here > > private > > for Some_Record use record > -- component rep spec here > end record; > > end; > > Are there cases in Ada where a record representation specification > cannot be deferred until the private part of the package? I'm told that > when this code was compiled with an Ada 95 compiler, that the record > rep spec had to be moved to immediately after the record declaration > for the code to compile correctly. I'm wondering if this is > > (a) illegal Ada83 code that our Ada83 compiler accepted anyway > (much like the use of unchecked_conversion on the left-hand side > of an assignment statement, as described in another thread), > > (b) legal Ada code that the other Ada compiler rejected anyway, or > > (c) OUCH! Ada83 code that is no longer valid Ada. I'm pretty sure (a) is the answer (a representation clause must occur in the same declaration list as the entity it refers to, and I believe that the private section constitutes a different declaration list), but regardless.... What possible purpose would placing the record rep spec in the private section serve when the record is not a private type? -Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 ` Bob Gilbert @ 1997-01-16 0:00 ` Fergus Henderson 1997-01-17 0:00 ` Ken Garlington 1 sibling, 0 replies; 23+ messages in thread From: Fergus Henderson @ 1997-01-16 0:00 UTC (permalink / raw) rgilbert@polaris.orl.mmc.com (Bob Gilbert) writes: >What possible purpose would placing the record rep spec in the >private section serve when the record is not a private type? The record rep spec may be an implementation detail, and you may want to preserve the distinction between interface and implementation. -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit" PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 ` Bob Gilbert 1997-01-16 0:00 ` Fergus Henderson @ 1997-01-17 0:00 ` Ken Garlington 1997-01-17 0:00 ` Bob Gilbert 1 sibling, 1 reply; 23+ messages in thread From: Ken Garlington @ 1997-01-17 0:00 UTC (permalink / raw) Bob Gilbert wrote: > > What possible purpose would placing the record rep spec in the > private section serve when the record is not a private type? (1) Indicates to the user of the code that it's not smart to make assumptions regarding the internal organization of the type (2) We have a tool that takes Ada code and inserts it into documentation developing using the Interleaf document processor. It makes keywords bold, and all of that, and it also has an option to suppress listing the information in the private section. So, if we don't want details to appear in our user documentation, we put it in the private section. > > -Bob -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Ken Garlington @ 1997-01-17 0:00 ` Bob Gilbert 1997-01-17 0:00 ` Robert A Duff 1997-01-20 0:00 ` Ken Garlington 0 siblings, 2 replies; 23+ messages in thread From: Bob Gilbert @ 1997-01-17 0:00 UTC (permalink / raw) In article <32DF9F55.7EA3@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> writes: > Bob Gilbert wrote: > > > > What possible purpose would placing the record rep spec in the > > private section serve when the record is not a private type? > > (1) Indicates to the user of the code that it's not smart to make > assumptions regarding the internal organization of the type Well, I guess there is a readability issue, but it seems like an abuse of the private declaration section. If I were looking at code where this was done, I would question what the user had intended. If you really don't want the user to make assumptions regarding the internals of the type, why not just go ahead and make it a private type? Placing the rep spec of a non-private type in the private section (if allowed) does not communicate any information to the compiler and may confuse the reader. Seems like some judicious use of comments might be in order. > (2) We have a tool that takes Ada code and inserts it into documentation > developing using the Interleaf document processor. It makes keywords > bold, and all of that, and it also has an option to suppress listing the > information in the private section. So, if we don't want details to appear > in our user documentation, we put it in the private section. Okay, but it still seems like a kludge and an abuse to me. That said, I do admit that sometimes having to include rep specs in the same declaration list as the entity it refers to, adds unnecessary verbosity to a package specification where the user would probably have little or no use for the knowledge of the type's representation. It might be useful to somehow identify a type as requiring a rep spec, but be able to provide the details elsewhere (say within the package body, or a representation section that works similar to the private section). Say something like: <hair-brained idea mode on> type T is {whatever}; for type T use private; -- Tell the user and compiler to look for -- further specifics about T's representation -- elsewhere in the package, perhaps even in -- the package body. -Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Bob Gilbert @ 1997-01-17 0:00 ` Robert A Duff 1997-01-17 0:00 ` Ken Garlington 1997-01-21 0:00 ` Bob Gilbert 1997-01-20 0:00 ` Ken Garlington 1 sibling, 2 replies; 23+ messages in thread From: Robert A Duff @ 1997-01-17 0:00 UTC (permalink / raw) In article <5bof0o$q0i@zeus.orl.mmc.com>, Bob Gilbert <rgilbert@polaris.orl.mmc.com> wrote: >In article <32DF9F55.7EA3@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> writes: [stuff about rep clauses in private parts] I agree with the reasons Ken stated for putting rep clauses in private parts. However, because of the freezing rules, it is not always possible to do that. Therefore, my style is to put the rep clause right after the type. This makes various changes less painful -- e.g. suppose you want to add something into the visible part that freezes the type. You'll have to move the rep clause to do that. Besides, a style rule that says "Put this info in the private part when possible, but otherwise put it in the visible part" seems kludgy to me -- knowing that rule, I have no idea what it means that a rep clause is in the visible part. Is it because clients are supposed to take advantage of it? Or is it merely because there happens to be some freezing point of the type, and the programmer couldn't put the rep clause in the private part. This problem existed in Ada 83, too. The freezing rules are slightly more permissive than the forcing occurrence rules of Ada 83, but not to the point where I've changed my mind about where to put rep clauses. IMHO the freezing/forcing rules are a serious flaw in the language. > type T is {whatever}; > for type T use private; -- Tell the user and compiler to look for > -- further specifics about T's representation > -- elsewhere in the package, perhaps even in > -- the package body. What is the point of this idea? Nobody said "Gee, wouldn't it be more readable if we knew a rep clause is coming later?" So it's unclear to me why you would want the above. Are you saying it makes life easier for the compiler? What matters is where the rep clause gets elaborated -- it's of no help to the compiler to know that it's coming, because the compiler can't "look ahead" to the rep clause and get any useful information, because that information might consist of non-static expressions (in a few rep clause cases), and anyway, you can't elaborate a variable declaration (for example) at run time without knowing how to represent the variable. Putting rep clauses in the body is not feasible. If you could do that, you might as well put the full type of a private type in the body, too, and completely eliminate the concept of a private part. This is certainly possible, but leads to a less-efficient run-time model. Or it leads to a different program-library model. It might be a reasonable idea, but it's not Ada. Ada 83 was designed so that the compiler never needs to look at bodies when compiling a client [unless it, ahem, wants to do something useful with pragma Inline], and so that private types can be implemented as efficiently as an equivalent non-private type. Incremental compilation was not considered a requirement. Note the different design decisions made by Eiffel, with respect to specs/bodies/private parts, given that the Eiffel design assumes that all Eiffel compilers will be incremental. - Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Robert A Duff @ 1997-01-17 0:00 ` Ken Garlington 1997-01-18 0:00 ` Robert A Duff 1997-01-21 0:00 ` Bob Gilbert 1 sibling, 1 reply; 23+ messages in thread From: Ken Garlington @ 1997-01-17 0:00 UTC (permalink / raw) Robert A Duff wrote: > > parts. However, because of the freezing rules, it is not always > possible to do that. Therefore, my style is to put the rep clause right > after the type. This makes various changes less painful -- e.g. suppose > you want to add something into the visible part that freezes the type. > You'll have to move the rep clause to do that. I guess this depends upon whether being unable to put the rep spec in the private area due to freezing rules is a "pathological" case (as has been described previously) or will occur relatively often. If the former, then a comment should do for those cases where the rep spec can't be placed in the private area. If the latter, then I think this potential incompatibility from Ada83 to Ada should be more widely advertised. I don't know which is the case; does anyone has real-world experience they could share? > Besides, a style rule > that says "Put this info in the private part when possible, but > otherwise put it in the visible part" seems kludgy to me -- knowing that > rule, I have no idea what it means that a rep clause is in the visible > part. Is it because clients are supposed to take advantage of it? Or > is it merely because there happens to be some freezing point of the > type, and the programmer couldn't put the rep clause in the private > part. This was even more of a problem prior to the advent of child packages. Was something outside the private part because the client needed it, or because some support package needed it. I think the style rule would be better stated as "If something is likely to change, or if the user should otherwise not depend on it, don't put it in the public part of the spec." (That's basically the way it's worded in SPC ADARTS, which we use.) Even if that rule can't always be followed, I think it's still a good rule. Assuming Ada will let you follow that rule most of the time (and, at least in my Ada83 experience, it would), then the exceptions should be relatively small and can be handled via comments. If you can't follow that rule most of the time, then "programming by contract" isn't possible and we might as well all use Eiffel :) > IMHO the freezing/forcing rules are a serious flaw in the language. > > > type T is {whatever}; > > for type T use private; -- Tell the user and compiler to look for > > -- further specifics about T's representation > > -- elsewhere in the package, perhaps even in > > -- the package body. "for type T use private"? Is that legal Ada? I've never used that before! I wouldn't say it as "Tell the user... to look for further specifics about T's representation elsewhere in the package." I would say "Tell the user... if he uses information gleaned outside the visible part of the package spec, he gets what he deserves." Basically, a higher-level abstraction of "using Unchecked_Conversion is both powerful and potentially dangerous." BTW, I can think of some cases where a rep spec might be OK to make public: A size clause, perhaps, for packages supporting system programming, or a record layout that conforms to some stable standard (assuming you can write it portably, or know it won't be ported). -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Ken Garlington @ 1997-01-18 0:00 ` Robert A Duff 1997-01-18 0:00 ` Ken Garlington 0 siblings, 1 reply; 23+ messages in thread From: Robert A Duff @ 1997-01-18 0:00 UTC (permalink / raw) In article <32E02DB1.6E06@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> wrote: >I guess this depends upon whether being unable to put the rep spec in >the private area due to freezing rules is a "pathological" case (as has >been described previously) or will occur relatively often. If the >former, >then a comment should do for those cases where the rep spec can't be >placed in the private area. If the latter, then I think this potential >incompatibility from Ada83 to Ada should be more widely advertised. I think you misunderstood what somebody said about "pathological". The upward incompatibilities are pathological, I believe. However, there are violations of the freezing rules that are not pathological, but these are not upward incompatibilities, since they existed in Ada 83. By and large, the Ada 95 rules are *more* permissive than the Ada 83 rules. Here's a violation: package P is type Point is record X, Y: Integer; end record; Origin: constant Point := (0, 0); private for Point use -- Illegal. record ... end record; end P; The above is illegal in both Ada 83 and Ada 95. But declaring a constant is a perfectly reasonable thing to do. Another example is passing a type to a generic instantiation -- perfectly reasonable, and prevents later rep clauses. Here's an example of an upward incompatility: package P is type R is record X: Integer; end record; task T is pragma Priority(X'Size); end T; private for R'Size use 32; -- Illegal in Ada 95. end P; The above is legal in Ada 83, and the pragma is IGNORED! This seems pretty pathological to me. Here's an example where the rules are more permissive: package P is type T is private; generic X: T; -- Illegal in Ada 83, now legal in Ada 95. package G is ... end G; private type T is ...; end P; The above seems like a pretty reasonable thing to do. >I don't know which is the case; does anyone has real-world experience >they >could share? It's happened to me more than once. But it doesn't happen a LOT. - Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-18 0:00 ` Robert A Duff @ 1997-01-18 0:00 ` Ken Garlington 1997-01-19 0:00 ` Robert A Duff 0 siblings, 1 reply; 23+ messages in thread From: Ken Garlington @ 1997-01-18 0:00 UTC (permalink / raw) Robert A Duff wrote: > > By and large, the Ada 95 rules are *more* > permissive than the Ada 83 rules. > Oh, I thought you were saying you saw many cases where Ada was _less_ permissive than Ada83, causing upward incompatibilities. > It's happened to me more than once. But it doesn't happen a LOT. Then a style rule suggesting the placement of rep specs in the private area shouldn't usually cause problems, and where it does, a comment should suffice. > > - Bob -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-18 0:00 ` Ken Garlington @ 1997-01-19 0:00 ` Robert A Duff 0 siblings, 0 replies; 23+ messages in thread From: Robert A Duff @ 1997-01-19 0:00 UTC (permalink / raw) In article <32E11C0E.697B@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> wrote: >Oh, I thought you were saying you saw many cases where Ada was _less_ >permissive than Ada83, causing upward incompatibilities. Ada 95 is less permissive in *some* cases, but I claim they are rare in real programs. If you can post your code, please do. And, as I said, I'll bet that the problem is not an upward incompatibility, but simply a bug in one or the other of the two 83/95 compilers. In *most* cases, the Ada 95 rules are the same as in Ada 83, and in some interesting cases, more permissive, and in some really weird cases, less permissive. Surely you agree that my "pragma Priority(R'Size);" example is pretty weird? >> It's happened to me more than once. But it doesn't happen a LOT. > >Then a style rule suggesting the placement of rep specs in the private >area shouldn't usually cause problems, and where it does, a comment >should suffice. Yeah, that's a reasonable attitude. It's just that I run into these problems from time to time (e.g. the generic example I gave in my earlier posting), and so I've decided that it's best to give up, and put the rep clause right after the type. Nonetheless, I agree with your *sentiment* -- that rep clauses are often private information. I agree that your style is reasonable, given that "a comment should suffice". I must say, that this sort of thing is what gives Ada a bad name, as being "too complex". And it's true -- the freezing rules (and the forcing occurrence rules of Ada 83) are, indeed, too complex. I'll eat my hat, if you can show me one professional Ada programmer who knows all the freezing/forcing rules! ;-) I (who wrote them) must look them up each time somebody asks a question -- I can't remember them off the top of my head. - Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Robert A Duff 1997-01-17 0:00 ` Ken Garlington @ 1997-01-21 0:00 ` Bob Gilbert 1997-01-22 0:00 ` Ken Garlington 1 sibling, 1 reply; 23+ messages in thread From: Bob Gilbert @ 1997-01-21 0:00 UTC (permalink / raw) In article <E46D5J.EM3@world.std.com>, bobduff@world.std.com (Robert A Duff) writes: > In article <5bof0o$q0i@zeus.orl.mmc.com>, > Bob Gilbert <rgilbert@polaris.orl.mmc.com> wrote: > >In article <32DF9F55.7EA3@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> writes: > [stuff about rep clauses in private parts] > > I agree with the reasons Ken stated for putting rep clauses in private > parts. However, because of the freezing rules, it is not always > possible to do that. Therefore, my style is to put the rep clause right > after the type. This makes various changes less painful -- e.g. suppose > you want to add something into the visible part that freezes the type. > You'll have to move the rep clause to do that. Besides, a style rule > that says "Put this info in the private part when possible, but > otherwise put it in the visible part" seems kludgy to me -- knowing that > rule, I have no idea what it means that a rep clause is in the visible > part. Is it because clients are supposed to take advantage of it? Or > is it merely because there happens to be some freezing point of the > type, and the programmer couldn't put the rep clause in the private > part. I too agree with Ken's reasons for putting rep clauses in the private part (to support a documentation tool and because the client should not have to be bothered with the details of the rep clause), but it seems to me if you don't want the client to know about the details of the type, why not go ahead and make the type private? This is where I find it odd to place only the rep clause in the private part for a type which is not private (as in Ken's example). > This problem existed in Ada 83, too. The freezing rules are slightly > more permissive than the forcing occurrence rules of Ada 83, but not to > the point where I've changed my mind about where to put rep clauses. > > IMHO the freezing/forcing rules are a serious flaw in the language. > > > type T is {whatever}; > > for type T use private; -- Tell the user and compiler to look for > > -- further specifics about T's representation > > -- elsewhere in the package, perhaps even in > > -- the package body. > > What is the point of this idea? Nobody said "Gee, wouldn't it be more > readable if we knew a rep clause is coming later?" No, but I think somebody said "Gee, it sure would be more readable if we could place the rep clause somewhere else and avoid making the client sift through a bunch of details that shouldn't matter to the client". The point of this idea is to inform the reader and compiler that a rep clause does exist for the type, just that it appears somewhere else. Perhaps the idea is unworkable, it was just an off-the-wall thought. > So it's unclear to me why you would want the above. Are you saying it > makes life easier for the compiler? I was looking at it more from a readability standpoint, can't say I know much about the compiler issues. > What matters is where the rep clause gets elaborated -- it's of no help > to the compiler to know that it's coming, because the compiler can't > "look ahead" to the rep clause and get any useful information, Not sure I understand. Why can't the compiler "look ahead"? > because > that information might consist of non-static expressions (in a few rep > clause cases), and anyway, you can't elaborate a variable declaration > (for example) at run time without knowing how to represent the variable. Like I said, the idea may not be workable. > Putting rep clauses in the body is not feasible. If you could do that, > you might as well put the full type of a private type in the body, too, > and completely eliminate the concept of a private part. This is > certainly possible, but leads to a less-efficient run-time model. This is along the lines of what I'm thinking for private types. Since you don't want the client to have much knowledge or control of a private type, why clutter the package spec with all the details? It's kind of a "you can look but don't touch" attitude which I think should be more of a "if you can't touch it, you don't need to be looking at it either". > Or it > leads to a different program-library model. It might be a reasonable > idea, but it's not Ada. Ada 83 was designed so that the compiler never > needs to look at bodies when compiling a client [unless it, ahem, wants > to do something useful with pragma Inline], and so that private types > can be implemented as efficiently as an equivalent non-private type. Okay, I accept that. I believe that generics also fall into this category of the compiler having to look at the bodies. -Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-21 0:00 ` Bob Gilbert @ 1997-01-22 0:00 ` Ken Garlington 1997-01-23 0:00 ` Art Schwarz 1997-01-24 0:00 ` Bob Gilbert 0 siblings, 2 replies; 23+ messages in thread From: Ken Garlington @ 1997-01-22 0:00 UTC (permalink / raw) Bob Gilbert wrote: > > I too agree with Ken's reasons for putting rep clauses in the private > part (to support a documentation tool and because the client should > not have to be bothered with the details of the rep clause), but it > seems to me if you don't want the client to know about the details of > the type, why not go ahead and make the type private? This is where > I find it odd to place only the rep clause in the private part for a > type which is not private (as in Ken's example). Maybe a simple example would help: --- package Device_IO is type Priority_Type is ( Normal, Urgent ); type Port_Type is range 0 .. 2#111#; type Data_Type is range 0 .. 16#FFF#; type Message_Type is record Priority : Priority_Type := Normal; Port : Port_Type; Data : Data_Type; end record; private for Message_Type use record Priority at 0 range 0 .. 0; Port at 0 range 1 .. 3; Data at 0 range 4 .. 15; end record; for Message_Type'Size use 16; end Device_IO; --- The way we intend a clients to read this is: You can assume that a Message has components Priority, Port, and Data, with the types shown. However, there are no guarantees as to the size of a Message, the placement of components within that message, the number of bits each component will use, etc. being stable from release to release. (In some cases, of course, you can use attributes to determine the current values, but it's up to the client to protect himself from changes in those attribute values.) What happens if I leave off the word private? In that case, I will be giving tacit permission for the user to do things like use Unchecked_Conversion to convert between Messages and 16-bit integers (as an example). You could argue that this is poor programming practice, but as least as far as how I understand the idea of programming by contract, if you put it in the visible part of the package spec, the assumption is that the client can take advantage of this information. I could certainly declare a Message as a private type, and provide operations to manipulate its contents. However, there are cases where I'm not really adding much to the strength of the interface by adding the extra code. -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-22 0:00 ` Ken Garlington @ 1997-01-23 0:00 ` Art Schwarz 1997-01-25 0:00 ` Ken Garlington 1997-01-24 0:00 ` Bob Gilbert 1 sibling, 1 reply; 23+ messages in thread From: Art Schwarz @ 1997-01-23 0:00 UTC (permalink / raw) > The way we intend a clients to read this is: You can > assume that a Message has components Priority, Port, and > Data, with the types shown. However, there are no guarantees > as to the size of a Message, the placement of components > within that message, the number of bits each component will > use, etc. being stable from release to release. (In some > cases, of course, you can use attributes to determine the > current values, but it's up to the client to protect himself > from changes in those attribute values.) Why not supply procedures (methods) for setting and retrieving values of interest within the record? One advantage (of procedures) is it allows explicit front-end validity checks. Another advantage may be to allow the type to be private. art schwarza@gdls.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-23 0:00 ` Art Schwarz @ 1997-01-25 0:00 ` Ken Garlington 0 siblings, 0 replies; 23+ messages in thread From: Ken Garlington @ 1997-01-25 0:00 UTC (permalink / raw) Art Schwarz wrote: > > > The way we intend a clients to read this is: You can > > assume that a Message has components Priority, Port, and > > Data, with the types shown. However, there are no guarantees > > as to the size of a Message, the placement of components > > within that message, the number of bits each component will > > use, etc. being stable from release to release. (In some > > cases, of course, you can use attributes to determine the > > current values, but it's up to the client to protect himself > > from changes in those attribute values.) > > Why not supply procedures (methods) for setting and retrieving > values of interest within the record? One advantage (of procedures) > is it allows explicit front-end validity checks. Another advantage > may be to allow the type to be private. As I noted at the end of my message, that's certainly an option. However, we found in practice that, assuming that we didn't really want to make the type private (that is, we wanted all of the operations usually available to a record declared in the visible part of the spec to be available), it was more error-prone to make it private and write all those access operations manually. This has been the SPC experience as well. I'm not sure I follow the logic of making a type private, in order to accrue the "advantage" of making a type private! If I wanted to narrow the operations available to the record, or I expected those operations to change over time, or if I wanted to enforce certain relationships between the components, then certainly it makes sense. Otherwise, it just adds unnecessary complexity, which is something you don't want - particularly in our systems, which are safety-critical. It's one of the nice things about Ada: you have very good control (most of the time, anyway) about how much you want to do explicitly, and how much you want created implicitly. It's not an "all or nothing" language with respect to visibility. > > art > schwarza@gdls.com -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-22 0:00 ` Ken Garlington 1997-01-23 0:00 ` Art Schwarz @ 1997-01-24 0:00 ` Bob Gilbert 1997-01-25 0:00 ` Ken Garlington 1 sibling, 1 reply; 23+ messages in thread From: Bob Gilbert @ 1997-01-24 0:00 UTC (permalink / raw) Ken Garlington <GarlingtonKE@lmtas.lmco.com> writes: > > Maybe a simple example would help: > --- > package Device_IO is > > type Priority_Type is ( Normal, Urgent ); > type Port_Type is range 0 .. 2#111#; > type Data_Type is range 0 .. 16#FFF#; > > type Message_Type is record > Priority : Priority_Type := Normal; > Port : Port_Type; > Data : Data_Type; > end record; > > private > > for Message_Type use record > Priority at 0 range 0 .. 0; > Port at 0 range 1 .. 3; > Data at 0 range 4 .. 15; > end record; > > for Message_Type'Size use 16; > > end Device_IO; > --- > > The way we intend a clients to read this is: You can > assume that a Message has components Priority, Port, and > Data, with the types shown. However, there are no guarantees > as to the size of a Message, the placement of components > within that message, the number of bits each component will > use, etc. being stable from release to release. (In some > cases, of course, you can use attributes to determine the > current values, but it's up to the client to protect himself > from changes in those attribute values.) This may be your intent, but if I were a client and unless I was very familar with this coding practice, I would only be confused (admittedly not a difficult task) by this. I would probably assume that the author had at one time defined Message_Type as a private type, and for some reason later decided to make Message_Type non-private by moving the declaration out of the private section and simply forgot to bring along the rep clause. > What happens if I leave off the word private? In that case, > I will be giving tacit permission for the user to do > things like use Unchecked_Conversion to convert between > Messages and 16-bit integers (as an example). You could argue that > this is poor programming practice, but as least as far as > how I understand the idea of programming by contract, if > you put it in the visible part of the package spec, the assumption is > that the client can take advantage of this information. I realize that you are attempting to offer a hint to the client that you really don't think he should be making use of the data representation to do things like Unchecked_Conversion, but I am afraid that the hint might easily be mis-interpreted or simply missed, while you have done nothing to prevent any possible misuse of the data. I would think some comments explaining why the rep clause is in the private section would be in order, but if you do that you might as well have the comment explicitly state that you don't want the client to make use of the rep clause, and leave the rep clause with the type declaration. > I could certainly declare a Message as a private type, and > provide operations to manipulate its contents. However, > there are cases where I'm not really adding much to the > strength of the interface by adding the extra code. I agree (sort of), but if it is so important to go to the trouble of offering hints to the client that the data representation is proprietary, then I think it is important enough to just go ahead and make the type private. While doing this still doesn't protect from Unchecked_Conversion, it does make a much stronger statement that you don't want the client messing with the data or performing any processing that requires knowledge of the data's representation. What I do agree with is that many times the representation clauses are of little or no value to the client and simply add clutter to a package spec making it more difficult to read. This is where I think it would be nice if there was a way to provide the rep clauses (or for that matter, the entire private section, after all if the client isn't supposed to have knowledge of the types details why put them all there in the private section to see?) somewhere else, perhaps even defering them to a place in the package body (although I understand that I am simply looking at this from a human readability side and there may well be serious compiler issues with this). -Bob ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-24 0:00 ` Bob Gilbert @ 1997-01-25 0:00 ` Ken Garlington 0 siblings, 0 replies; 23+ messages in thread From: Ken Garlington @ 1997-01-25 0:00 UTC (permalink / raw) Bob Gilbert wrote: > > Ken Garlington <GarlingtonKE@lmtas.lmco.com> writes: > > > > Maybe a simple example would help: > > --- > > package Device_IO is > > > > type Priority_Type is ( Normal, Urgent ); > > type Port_Type is range 0 .. 2#111#; > > type Data_Type is range 0 .. 16#FFF#; > > > > type Message_Type is record > > Priority : Priority_Type := Normal; > > Port : Port_Type; > > Data : Data_Type; > > end record; > > > > private > > > > for Message_Type use record > > Priority at 0 range 0 .. 0; > > Port at 0 range 1 .. 3; > > Data at 0 range 4 .. 15; > > end record; > > > > for Message_Type'Size use 16; > > > > end Device_IO; > > --- > > > > The way we intend a clients to read this is: You can > > assume that a Message has components Priority, Port, and > > Data, with the types shown. However, there are no guarantees > > as to the size of a Message, the placement of components > > within that message, the number of bits each component will > > use, etc. being stable from release to release. (In some > > cases, of course, you can use attributes to determine the > > current values, but it's up to the client to protect himself > > from changes in those attribute values.) > > This may be your intent, but if I were a client and unless I was > very familar with this coding practice, I would only be confused > (admittedly not a difficult task) by this. I would probably assume > that the author had at one time defined Message_Type as a private > type, and for some reason later decided to make Message_Type > non-private by moving the declaration out of the private section > and simply forgot to bring along the rep clause. Then, presumably, you would also feel the same way about this code? --- package Key_Manager is type Key is private; type Key_Index is range 1 .. 10; type Key_List is array (Key_Index range <>) of Key; function Supplied_Key return Key; function Existing_Key ( New_Key : Key; Reference_List : Key_List ) return Boolean; private type Key is range 1 .. 1000; -- perhaps Key_List was once private, and was moved from here to -- the visible spec, along with Key_Index? Why wasn't Key also moved? -- A programming error? end Key_Manager; --- It seems odd that someone reading code, and seeing something defined after a keyword "private", would first assume a programming error! I would think the more straight-forward answer would be more appropriate: It's declared private because it's supposed to _be_ private. > > > What happens if I leave off the word private? In that case, > > I will be giving tacit permission for the user to do > > things like use Unchecked_Conversion to convert between > > Messages and 16-bit integers (as an example). You could argue that > > this is poor programming practice, but as least as far as > > how I understand the idea of programming by contract, if > > you put it in the visible part of the package spec, the assumption is > > that the client can take advantage of this information. > > I realize that you are attempting to offer a hint to the client > that you really don't think he should be making use of the data > representation to do things like Unchecked_Conversion, but I am > afraid that the hint might easily be mis-interpreted or simply > missed, while you have done nothing to prevent any possible misuse > of the data. I don't know of any way to "prevent" _any_ possible misuse of the data. Certainly, defining the type as private doesn't do it -- consider the use of the private Key type above with this code... with Key_Manager; with Unchecked_Conversion; procedure KeyTest is type My_Key is range 1 .. 1000; function Make_Key is new Unchecked_Conversion ( Key_Manager.Key, My_Key ); Public_Key : My_Key := Make_Key (Key_Manager.Supplied_Key); begin if Public_Key > 1 then Public_Key := 1; end if; end KeyTest; What we _can_ do is to make sure that the user doesn't think that a declaration _guarantees_ something regarding the user interface. If they do something like this, and it breaks in a later release, we say: "If we were going to keep the size, order, etc. of the components consistent from release to release, we would have defined the package that way!" > I would think some comments explaining why the rep > clause is in the private section would be in order, but if you do > that you might as well have the comment explicitly state that you > don't want the client to make use of the rep clause, and leave the > rep clause with the type declaration. A comment like... private -- The following information is private. Don't take advantage -- of the information here. Really. We're not kidding! :) This is essentially what our documentation system does, by not displaying the private area to the client. You can't take advantage of something that you don't _see_. > > > I could certainly declare a Message as a private type, and > > provide operations to manipulate its contents. However, > > there are cases where I'm not really adding much to the > > strength of the interface by adding the extra code. > > I agree (sort of), but if it is so important to go to the trouble > of offering hints to the client that the data representation is > proprietary, then I think it is important enough to just go ahead > and make the type private. I don't want _all_ of the data representation to be proprietary - just the parts described in the rep spec! > While doing this still doesn't protect > from Unchecked_Conversion, it does make a much stronger statement > that you don't want the client messing with the data or performing > any processing that requires knowledge of the data's representation. So, if you see a type declared in the private part, you understand what it means, but not if you see a rep spec? Seems shaky logic to me... > > What I do agree with is that many times the representation clauses > are of little or no value to the client and simply add clutter to > a package spec making it more difficult to read. This is where I > think it would be nice if there was a way to provide the rep clauses > (or for that matter, the entire private section, after all if the > client isn't supposed to have knowledge of the types details why > put them all there in the private section to see?) somewhere else, > perhaps even defering them to a place in the package body (although > I understand that I am simply looking at this from a human readability > side and there may well be serious compiler issues with this). Or, you can do what we do (suppress the viewing of the private area to the client), and get both more human-readable code, and provide the compiler what it needs! > > -Bob -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-17 0:00 ` Bob Gilbert 1997-01-17 0:00 ` Robert A Duff @ 1997-01-20 0:00 ` Ken Garlington 1 sibling, 0 replies; 23+ messages in thread From: Ken Garlington @ 1997-01-20 0:00 UTC (permalink / raw) Bob Gilbert wrote: > > If you really don't want the user to make assumptions > regarding the internals of the type, why not just go ahead and > make it a private type? Because I may be willing for the client to use information about the number, names, and types of record components (for example), but not their starting bit position, bit width, etc. > Placing the rep spec of a non-private > type in the private section (if allowed) does not communicate any > information to the compiler and may confuse the reader. Our experience so far is that this helps the reader. (It's in an interface to an OS we develop, with several end users spread out over several companies). I don't know if it communicates any more information to the compiler; since we write the code with an emphasis on communicating to the human reader, we don't get too excited about compiler issues (so long as the code works, of course!) > Seems > like some judicious use of comments might be in order. Why write comments for things that Ada allows you to express directly? > > > (2) We have a tool that takes Ada code and inserts it into documentation > > developing using the Interleaf document processor. It makes keywords > > bold, and all of that, and it also has an option to suppress listing the > > information in the private section. So, if we don't want details to appear > > in our user documentation, we put it in the private section. > > Okay, but it still seems like a kludge and an abuse to me. OK. As I said, it seems to work well in real life, so we're sticking to it. :) > > That said, I do admit that sometimes having to include rep specs in > the same declaration list as the entity it refers to, adds unnecessary > verbosity to a package specification where the user would probably > have little or no use for the knowledge of the type's representation. Well, there you go! > It might be useful to somehow identify a type as requiring a rep > spec, but be able to provide the details elsewhere (say within > the package body, or a representation section that works similar to > the private section). Say something like: <hair-brained idea mode on> > > type T is {whatever}; > for type T use private; -- Tell the user and compiler to look for > -- further specifics about T's representation > -- elsewhere in the package, perhaps even in > -- the package body. Today, of course, you can do this with one less line (don't need the "for type..."), which is even _less_ verbose! You seem to believe that the client of a package is usually expected to read the private part. Our philosophy is that they probably shouldn't - when they hit "private", they stop reading (and as I said, we even enforce that in our user documentation!) > > -Bob -- LMTAS - The Fighter Enterprise - "Our Brand Means Quality" For job listings, other info: http://www.lmtas.com or http://www.lmco.com ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 Question about record rep spec placement Ken Garlington 1997-01-15 0:00 ` Norman H. Cohen 1997-01-15 0:00 ` Bob Gilbert @ 1997-01-16 0:00 ` Jeff Creem 1997-01-16 0:00 ` Jerome Desquilbet 3 siblings, 0 replies; 23+ messages in thread From: Jeff Creem @ 1997-01-16 0:00 UTC (permalink / raw) In article <32DCFDAA.2656@lmtas.lmco.com>, Ken Garlington <GarlingtonKE@lmtas.lmco.com> wrote: >We have some Ada83 code that looks like the following: > >package Some_Package is > > type Some_Record is record > -- components here > end record; > > -- some arbitrary declarations here > >private > > for Some_Record use record > -- component rep spec here > end record; > >end; I have seen this on some compilers when the "some arbitrary declarations here" contain any reference to the Some_Record in a way that makes the compiler have to make some decision about the size of Some_Record. This may not be the problem but it is something to look at. Jeff ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Question about record rep spec placement 1997-01-15 0:00 Question about record rep spec placement Ken Garlington ` (2 preceding siblings ...) 1997-01-16 0:00 ` Jeff Creem @ 1997-01-16 0:00 ` Jerome Desquilbet 3 siblings, 0 replies; 23+ messages in thread From: Jerome Desquilbet @ 1997-01-16 0:00 UTC (permalink / raw) To: Ken Garlington Ken Garlington wrote: > > We have some Ada83 code that looks like the following: > > package Some_Package is > > type Some_Record is record > -- components here > end record; > > -- some arbitrary declarations here > > private > > for Some_Record use record > -- component rep spec here > end record; > > end; > [...] > when this code was compiled with an Ada 95 compiler, that the record > rep spec had to be moved to immediately after the record declaration > for the code to compile correctly. This kind of contruction is legal in Ada 83 and in Ada 95. And I think this is really good style: you may want to hide in a private part the implementation details. The following example compiles with my Ada 83 and Ada 95 compilers: with System; package Communication is type Date is range 0 .. 3600; type Word is range -(2 ** 31) .. (2 ** 31) - 1; type Message is record Send_Date : Date; Content : Word; end record; private for Date'Size use 16; for Word'Size use 32; for Message use record Send_Date at 0 range 0 .. Date'Size - 1; Content at (Date'Size / System.Storage_Unit) range 0 .. Word'Size - 1; end record; for Message'Size use Date'Size + Word'Size; end Communication; You are able to document this as: with System; package Communication is type Date is range 0 .. 3600; type Word is range -(2 ** 31) .. (2 ** 31) - 1; type Message is record Send_Date : Date; Content : Word; end record; private ... end Communication; ______________________________________________________________________ Jerome Desquilbet jDesquilbet@Rational.COM ' ^ ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~1997-01-25 0:00 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1997-01-15 0:00 Question about record rep spec placement Ken Garlington 1997-01-15 0:00 ` Norman H. Cohen 1997-01-16 0:00 ` Ken Garlington 1997-01-17 0:00 ` Robert A Duff 1997-01-18 0:00 ` Ken Garlington 1997-01-15 0:00 ` Bob Gilbert 1997-01-16 0:00 ` Fergus Henderson 1997-01-17 0:00 ` Ken Garlington 1997-01-17 0:00 ` Bob Gilbert 1997-01-17 0:00 ` Robert A Duff 1997-01-17 0:00 ` Ken Garlington 1997-01-18 0:00 ` Robert A Duff 1997-01-18 0:00 ` Ken Garlington 1997-01-19 0:00 ` Robert A Duff 1997-01-21 0:00 ` Bob Gilbert 1997-01-22 0:00 ` Ken Garlington 1997-01-23 0:00 ` Art Schwarz 1997-01-25 0:00 ` Ken Garlington 1997-01-24 0:00 ` Bob Gilbert 1997-01-25 0:00 ` Ken Garlington 1997-01-20 0:00 ` Ken Garlington 1997-01-16 0:00 ` Jeff Creem 1997-01-16 0:00 ` Jerome Desquilbet
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox