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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!inmet!stt From: stt@inmet.inmet.com Newsgroups: comp.lang.ada Subject: Re: Use of "is separate" and compilatio Message-ID: <20600021@inmet> Date: 27 Nov 89 20:29:00 GMT Nf-ID: #R:<8911201444.AA15697@chance.mitre:-37:inmet:20600021:000:3462 Nf-From: inmet.inmet.com!stt Nov 27 15:29:00 1989 List-Id: We have built a number of very large Ada systems at Intermetrics, and our customers have built some even bigger ones. As a result of this we have built up a very strong prejudice *against* the use of subunits (aka "is separates"). Instead, we try to structure our system as a series of medium size packages (about 500-2500 lines each), using either a functional or object-oriented structuring. Ideally, each of these packages represents a well-defined, relatively self-contained component of the system. When making a change or trying to understand a particular feature of the system, it is generally only necessary to look at the single medium-size package which implements it. Furthermore, most of the candidates for low-level, small-chunk-of-code reuse, are within a single package. Subunits foul up this structure in a number of ways: First and foremost, a single subunit is in no way "self-contained." It has unlimited visibility into its parent unit, representing a very "broad" interface (the worst kind). Secondly, when editing a subunit, other related code is not immediately available, so we have found that programmers working on a heavily "subunited" program tend to reinvent the wheel repeatedly, rather than noticing a similar sequence of code in another subprogram of the same package, and separating off that logic as a local shared subprogram of the package. Thirdly, subunits cause havoc with sophisticated optimizers, especially subunits within subprograms. When calling a separately-compiled subunit the compiler must assume the worst: that the subunit accesses and/or updates all objects it can see, meaning that all local variables visible to the subunit must be stored back into memory from registers before the call, and reloaded afterward. Finally, they tend to allow single library units to grow without bound. Often when a subsystem grows too big, it is wise to split it up into a number of packages, each with a narrower purpose. When using subunits, the tendency is to instead just keep adding more and more functionality into a single package. As far as recompilation, subunits are also bad news, since almost all compilers will recompile *all* subunits when any change is made to the enclosing parent unit, including just the addition of another subunit. Of course, the total amount of code is no greater than if the package had not been "subunited" (presuming you resisted the growth-without-bound phenomenon), but most compilers will compile a single 2500-line package much faster than 50 50-line subunits. Of course you win when the only change to be made was in a single subunit, but in our experience, that incentive causes many of the problems with subunits -- the avoidance of restructuring of the package. Many bugs can best be fixed by modest restructuring of the implementation of a package. Any attempt at restructuring in the presence of subunits causes them all to be recompiled again. I should mention that reasonable people differ on this whole "subunit" issue, and there are selected places where a subunit can be extremely useful, to, for instance, isolate a very small bit of host-dependent code. However, on balance, I would regard them almost as bad as a goto -- to be used only when all other avenues have been exhausted. As Lori Clarke, et al, said in their classic critique of Ada subunits long ago, "nesting in Ada is for the birds." S. Tucker Taft Intermetrics, Inc. Cambridge, MA 02138