From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e977cd3ab4e49fef X-Google-Attributes: gid103376,public From: Ken Garlington Subject: Re: Question about record rep spec placement Date: 1997/01/25 Message-ID: <32EA8997.38E5@lmtas.lmco.com> X-Deja-AN: 212208643 references: <32E6A985.6C4B@lmtas.lmco.com> <5caf8c$e14@zeus.orl.mmc.com> content-type: text/plain; charset=us-ascii organization: Lockheed Martin Tactical Aircraft Systems mime-version: 1.0 newsgroups: comp.lang.ada x-mailer: Mozilla 3.01 (Win95; U) Date: 1997-01-25T00:00:00+00:00 List-Id: Bob Gilbert wrote: > > Ken Garlington 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