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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,dbf84a1c2794f4fb X-Google-Attributes: gid103376,public From: stt@houdini.camb.inmet.com (Tucker Taft) Subject: Re: packages and private parts Date: 1997/02/07 Message-ID: #1/1 X-Deja-AN: 215114954 sender: news@inmet.camb.inmet.com (USENET news) x-nntp-posting-host: houdini.camb.inmet.com references: <32FB27FF.794BDF32@innocon.com> organization: Intermetrics, Inc. newsgroups: comp.lang.ada Date: 1997-02-07T00:00:00+00:00 List-Id: Jeff Carter (carter@innocon.com) wrote: : Norman H. Cohen wrote: : > : > I strongly disagree. One of the great strengths of child units is : > precisely that you can use them to, in effect, extend packages in ways : > that the original author did not anticipate. This is precisely what : This is the big problem with child packages. To correct the non-existent : problem of subsystems, the language now allows anybody to create a child : of any (non-language-defined) package, with full visibility of a private : type's internal structure, in a way which is difficult if not impossible : to detect. So after all the hard work by a "great designer" to design a : safe, robust package, someone who is not so great can hack a child and : mess with the internals, destroying the safety and robustness. A child package is only included in a program if you mention it in a "with" clause. So don't "with" a child package you don't trust. Just the existence of a child package doesn't destroy anything. It is best to think of child packages as an abstraction structuring mechanism. You (or the "hacker") could choose of course to just edit (or rewrite) the original package, making it bigger and bigger, and forcing massive recompilations every time you do so. Alternatively, you can structure your abstraction as a (potentially growing) set of child packages, reducing the effect of any particular change to those clients dependent on the child being changed. In my view, the point of encapsulation and information hiding is not really to "hide" something, or to prevent it from being changed (or "destroyed' ;-). Rather it is to make it easier to find all code that depends on a particular implementation choice, so that when the implementation is inevitably changed, you can track down all the potentially affected code and fix it as necessary. In Ada 95, all such code is restricted to a single "subsystem," rooted at the package containing the private declaration. The child packages of a subsystem can be used to provide additional operations on a private type that were not anticipated when the original package was defined, or that are needed by only a subset of the clients. The alternative of making the type non-private is clearly worse, as is bloating up the original package with operations that only a subset of the clients would ever need. The C++ and Java equivalent to Ada's private declarations are roughly the "protected" declarations (C++/Java "private" is analogous to "package body" declarations). However, the protected declarations are visible to all subclasses, no matter where they are or who "owns" them. If a protected declaration is changed, an unbounded amount of code may need changing, and much of it might not be owned by or available to the team in charge of the original class. With Ada 95, presuming you establish "owners" on the basis of subsystems (which seem wise), then since all the code that might be affected by a change is part of the same subsystem, it can be found and fixed relatively easily and with minimal cross-organization traumas. If you get the original package from a third party, then you might still want to extend it in some way. If you do that, then you would want to establish a local "owner" of the subsystem rooted at the original third-party package, and that local owner would be responsible for all children added by your organization, and would be responsible for updating them when your organization received a new version from the third party. By the way, I don't recommend putting all type extensions of a tagged type in children of the package defining the type. Children should be used primarily for exporting additional operations of the abstraction rooted at their parent. If to write certain type extensions you need some additional operations on the parent type, then define those additional operations in a child package. The type extensions can "with" that child package to accomplish their job. Of course some type extensions are really part of the same abstraction as the parent type, and those make perfect sense to be in a child package. : Jeff Carter : Innovative Concepts, Inc. -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Cambridge, MA USA