-*- Mode: Text; Fonts: Ct18b -*- Chapter 13.3.1: NAMED COLLECTIONS OF DECLARATIONS One of the simplest uses of packages is for the logical grouping of objects and types. This application benefits maintainability by factoring out common data, objects, and types and placing their definition in one location. This definition may then be used by any other program unit. As changes are made, only the one package must be altered, thus ensuring consistency. For example, in a system that requires an earth model, such as a guidance program or a mapping application, it is important to maintain a set of constants that every other program unit may reference. We may package this set as follows: package METRIC_EARTH_CONSTANTS is EQUATORIAL_RADIUS : constant:=6_378.145; --km GRAVITATION_CONSTANT : constant:=3.986_012e5; --km**3/sec**2 SPEED_UNIT : constant:=7.905_368_28; --km/sec TIME_UNIT : constant:=806.811_874_4; --sec end METRIC_EARTH_CONSTANTS; In this example, there are no other program units defined in the specification; so we may omit the package body. As an even better (safer) implementation, we could export types defining kilometers and seconds, and then declare the numbers as constants of that specific type. In this manner, we would prevent a user from applying a constant with the wrong units. To ensure portability, predefined types such as FLOAT should not be used. In fact, in our example above, we used numeric constants (of type universal_real) instead of naming constants of type FLOAT. As another application, it is often useful to collect a set of logically related types. In a system that manipulates dates, it would be useful to package day, month, and year types. For example: package DATE_INFORMATION is type DAY_NAME is (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY); type DAY_VALUE is range 1..31; type MONTH_NAME is (JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER); type YEAR_VALUE is range 0..INTEGER'LAST; end DATE_INFORMATION; Again, a package body is not required to complete the package declaration. A few comments on style are in order here. In the example above, note that we chose to apply meaningful names, even though they take longer to write. We do this to enhance understandability. Note also that the packages in both examples are relatively small. If package specifications are made too large (beyond our Hrair limit), they become unreadable and difficult to understand. In such a case, the programmer probably missed factoring the data one more level. It would then be appropriate to create subpackages (packages nested within another package). Also, if packages are used as collections of declarations, they should not be used as if they were FORTRAN COMMONs or JOVIAL COMPOOLs. Such an application turns them into nothing more than named pools of global data, which then makes Ada programs reflect the topology of first or second generation languages. This clearly is not in the spirit of Ada and, furthermore, it defeats much of the power of the language.