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.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,63a41ccea0fc803a X-Google-Attributes: gid103376,public From: "John G. Volan" Subject: Re: Naming of Tagged Types and Associated Packages Date: 1998/08/08 Message-ID: <35CD0A8E.21D64380@sprintmail.com> X-Deja-AN: 379299590 Content-Transfer-Encoding: 7bit References: <6qfp80$p0u$1@nnrp1.dejanews.com> Content-Type: text/plain; charset=us-ascii Organization: EarthLink Network, Inc. Mime-Version: 1.0 Reply-To: johnvolan@sprintmail.com Newsgroups: comp.lang.ada Date: 1998-08-08T00:00:00+00:00 List-Id: Matthew Heaney wrote: > > doylep@ecf.toronto.edu writes: > > > 2. It allows you to avoid contrivances by permitting things like this: > > > > class CAR > > > > feature > > steering_wheel : STEERING_WHEEL > > > > end > > > > What else are you going to call the steering wheel? A > > direction_control_device? I think any other name would be contrived. > > I usually qualify auxiliary types with the name of the "main" type, so I > probably would have named the type Car_Steering_Wheel, and the object > Steering_Wheel. > > package Cars is > > type Car_Steering_Wheel is ...; > > type Car is > tagged record > Steering_Wheel : Car_Steering_Wheel; > end record; > > This is the convention used in package Text_IO, for type File_Mode. > > This is another reason why use clauses are safe. The naming convention > makes it obvious that type Car_Steering_Wheel is declared package Cars. Matthew, you seem to be confusing P. Doyle's point. (You seem to have lost something in translation from Eiffel to Ada, not surprising.) I'm fairly certain that P. Doyle intended the "STEERING_WHEEL" type to be a primary type in its own right, declared within its own module, and not some auxiliary type subordinate to the "CAR" type, somehow declared within the same module. (In fact, since P.D.'s example was Eiffel, the "STEERING_WHEEL" type would _be_ its own module). So your answer begs the question: What, then, would you call an instance of the "CAR" type? In Eiffel, the answer is fairly simple: car : CAR The equivalent in Java would be: Car car; (Let's please assume that we're in some context where there is only one instance of the "CAR" type that happens to be of interest, so there's no particular reason to attach some modifying adjective that distinguishes that instance from any other instance of the "CAR" type. This is by no means a rare situation -- the above might be an argument to a method.) It's interesting to note that the reasons this works out are very different in Java as opposed to Eiffel: Java (like C++ and Smalltalk before it) is case-sensitive. This allows programmers to get the _effect_ of two namespaces, by adopting a naming convention in which a class name and a variable name may be the "same" identifier, but differing in case. In reality, the compiler considers "car" and "Car" to be two completely distinct identifiers. Java really has only one namespace (in any given scope), but this naming convention effectively segregates that namespace into two mutually-exclusive subsets. Since the convention follows a regular rule (class names initial uppercase, variable names initial lowercase), it is immediately obvious to the programmer's eye into which subset a given identifier falls. In Eiffel, the situation appears to be reversed: The compiler is case-insensitive, but there actually _are_ two namespaces for type names vs. entity names. (That's interesting to me -- I had not known that before.) So the Eiffel naming convention (type names all-uppercase; entity names all-lowercase or mixed case) is purely a cosmetic convenience for the human reader. To the compiler, "car" and "CAR" really _are_ the same identifier, but the syntactic context allows the compiler to distinguish which namespace to resolve the identifier against. Ada has only one namespace (within any given scope). Since Ada is also case-insensitive, the only recourse is to come up with completely different identifiers for a variable and for its type. But the only difference between a variable and its type is that the former is at a "base" level of abstraction, while the latter is at a "meta" level of abstraction. Otherwise, they're just two manifestations of a single "concept". The base/meta distinction is fairly subtle; people tend to want to gloss over it, and just use the same noun for both "car" as a variable, and "CAR" as a type. It seems to me that if one is forced to come up with distinct identifiers for a type and an (arbitrary) instance of that type, then the difference between the identifiers should reflect this base/meta distinction. Thus, the Cohen style: Car : Car_Type; In other words, the thing on the left hand side of the colon is a _car_, while the thing on the right hand side a _type_ (the "car" type). The old Booch style: The_Car : Car; also reflects this same base/meta distinction. Using the definite article in the variable name makes it clear that we're talking about a specific instance of the concept (at the "base" level of abstraction), whereas using the indefinite noun "Car" by itself indicates we're talking at a more abstract level (the "meta" level). It seems to me that any scheme that contrives different identifiers without playing into the base/meta distinction is an ad hoc scheme. Matthew, you seem to be advocating a variation on the "abbreviation" approach: Come up with some wordy phrase for a type name, and then arbitrarily lop off some part of that phrase to come up with a variable name. That seems ad hoc to me. If it was important enough to say, in a type name, that something is a "Car_Steering_Wheel" (as opposed to, perhaps, a "Truck_Steering_Wheel"), then why isn't it also important to say "Car_Steering_Wheel" in the variable name too? Why arbitrarily lop off the "Car_" part? On the other hand, if the "Car_" part is already understood (because the type is already nested inside a "Cars" package), then why bother with the "Car_" part in the first place, in the type name? Isn't that just noise? If the type name were only "Steering_Wheel", what would you propose lopping off from that to make the variable name? The "Steering_" part? Then why did we need to say "Steering_" in the type name? Isn't that just noise too? On the other hand, what if the car doesn't just have a steering wheel, but also has four drive wheels? Then don't we need to say "Steering_Wheel" and "Drive_Wheel", not only in the type names but also in the variable names too? What do we lop off where? And what do you propose we lop off of the type name "Car" to make a variable name? Alternatively, what "noise" word shall we tack onto the type name so we can then lop it off? A naming convention should be systematic, mechanical, predictable and transparent. That means that it should take NO THOUGHT to apply it, or to interpret the results. The argument that this limits a programmer's creativity is specious. There's plenty of opportunity for a software engineer to be creative just in coming up with concepts like "Car" or "Steering_Wheel" to program up. That's the real critical design step. Going on to split each of these into base-level variable names and meta-level type names should be a mechanical process, not something to waste time over -- either for the code-writer, or more importantly for the code-reader. IMHO, the styles that Java and Eiffel allow meet the criteria of being systematic, mechanical, etc. In Ada, Cohen and Booch styles (and Jean-Pierre Rosen's style, as a variation on Booch) also meet these criteria, although at the cost of adding systematic "noise" (i.e., "_Type" or "The_"). But I am at a loss to see how Heaney style would meet these criteria in the most general case. -- Signature volanSignature = new Signature ( /*name: */ "John G. Volan", /*employer: */ "Raytheon/TI Advanced C3I Systems, San Jose", /*workEmail: */ "johnv@ac3i.dseg.ti.com", /*homeEmail: */ "johnvolan@sprintmail.com", /*selfPlug: */ "Sun Certified Java Programmer", /*twoCents: */ "Java would be even cooler with Ada95's " + "generics, named parameter passing, etc...", /*disclaimer:*/ "These views not packaged in COM.ti.dseg.ac3i.*, " + "so loading them throws DontQuoteMeError. :-) " );