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,2078dddcdcd8d83 X-Google-Attributes: gid103376,public From: "John G. Volan" Subject: Warning: Religious naming convention discussion :-) [was: assign help!!] Date: 1997/05/08 Message-ID: <33727EEA.2092@sprintmail.com> X-Deja-AN: 240324714 References: <5kjvcv$evt@news.cis.nctu.edu.tw> <5kn8ko$jcc@top.mitre.org> <1997May7.201035.2439@nosc.mil> Reply-To: johnvolan@sprintmail.com Newsgroups: comp.lang.ada Date: 1997-05-08T00:00:00+00:00 List-Id: Charles H. Sampson wrote: > > In article <5kn8ko$jcc@top.mitre.org>, > Michael F Brenner wrote: > > > > ... I advise the following: > > (A) make all of the type names plural English noun phrases, i.e. > > change page_type to pages, text_line to text_lines, > > natural to columns, natural to rows, etc. (This will make > > better use of the type checking facility, but more diagnostic > > messages will reveal the rest of the bugs, and your program > > will be more readable AS AN ENGLISH SENTENCE. [snip] > This has nothing to do with the original poster's issue, but I > have to disagree with you on this naming convention. I agree with Charles, in that I disagree :-) with Michael's particular choice of a naming convention. However, I also disagree :-) with Charles' naming convention, see below... "Readability AS an English sentence" is not a very well-defined or well-bounded goal (although it is a worthy one, and I do applaud the sentiment behind it). Trying to get a programming language to mimic any natural language, and yet still fulfill its purpose to unambiguously specify programs, is a very hard problem (probably NP complete :-). English is particularly hard, because it is so fluid and flexible and ambiguous that almost any sequence of words could be interpreted as a sentence (given a certain poetic frame of mind). Yes, a naming convention for programming shouldn't gratuitously diverge from standard usage of English (or whatever your natural language happens to be). (4 instnc, IMHO, rsortng to ad hoc abrvtns z defntly bad 4m!) But, to be useful, a naming convention should be unambiguous, prosaic, and systematic -- in fact it should be downright mechanical! By this I mean that it should consists of simple, unambiguous rules, which (1) a program author could apply, with very little mental effort, to generate all the identifiers needed; and which (2) the readers of a program could apply, with very little mental effort, to instantly comprehend what those identifiers stand for. The more mechanical the rules, the better -- NOT because we're trying to take away from a programmer's "creativity". If anything, a mechanical naming convention can _liberate_ programmers so they can spend their energies applying their "creativity" to other more important goals -- like, actually writing programs that work! :-) A naming convention also ought to be "semantically economical." By this I mean that, once a programmer has come up with a word describing a certain concept in the target application (for instance, the name of a class of objects), he shouldn't be force to invent a _different_ word to represent the same concept -- in fact, doing so just serves to confuse the readers. Yet in Ada95, the same concept often must be mapped to several program entities, and they can't all get the same identifier: For example, let's say in our warfighting application domain we have a notion of a class of "Target" objects. An Ada95 programmer will tend to want to use "Target" as the name of a type, _and_ as the name of an object (variable, constant, parameter, record component) of that type, _and_ as the name of a function that returns a value of that type, _and_ as the name of the package that encapsulates the type and its primitive operations. But obviously something has to give here. (A similar problem arises in most other languages, too.) The only way to meet the goal of being "semantically economical" is to find some simple scheme for taking the basic name of your concept and "marking" it in some systematic way, to generate a family of derived identifiers. (More on this in a moment...) > I much prefer the > one advocated by Ada Quality and Style: Type names should be general > singular nouns and object names should be specific singular nouns, [snip] > (I don't just > prefer it. I had some influence on its being in AQ&S that way.) Oh, so you're the one ... :-) Seriously, I once was an staunch advocate of this very approach, but I have since come to find it unwieldy and impractical. By the criteria I described above, it fails miserably: The distinction between "general" and "specific" nouns is quite ambiguous and subjective, depending on context and point of view. It may take a lot of effort and hours spent poring over Roget's Thesaurus hunting for synonyms, and then more agonized hours deciding which synonym is more "general" and which more "specific". And for what? A percentage of your readers would've made the opposite decision you made, so where does that leave readability? Add to that the challenges of object-oriented programming, where you have "specific" subclasses inheriting from "general" subclasses. Would "specific" noun phrases like "Enemy_Target" and "Friendly_Target" represent _objects_ of type "Target", or would they be _types_ derived from "Target"? The only way I could find to hammer this into something even remotely approaching a systematic scheme was to follow Grady Booch's lead, and distinguish "definite" versus "indefinite" noun phrases. An unmarked noun such as "Target" is an "indefinite" noun phrase in English -- it does not refer to any specific instance of the concept. So that seemed appropriate as the name of a type. A "definite" noun phrase seemed appropriate as the name for a specific instance. To form a "definite" noun phrase, you have to add some "definite" adjective to the base noun, e.g.: The_Target : Target; This_Target : Target; That_Target : Target; and so forth. In fact, I used to resort to tacking "The" onto most every object name, as a sort of universal default marker for "objectness." (I made a distinction for record components: Since they "belong" to their record, I used the possessive "Its" instead of "The". For instance you'd get things like: "The_Target.Its_Location.Its_Latitude".) I used to push this scheme quite vehemently. However, the trouble with this approach is that it favors short type names at the expense of longer object names. Yet object names ought to be shorter, because they are referenced more often, in contexts that are more demanding on line-length (e.g., statements and expressions). Whereas types are used in contexts where you have more leeway to be verbose (e.g., in object declarations and parameter profiles). I have now come around to accept Norman Cohen's approach: An unmarked noun should be reserved for an object, e.g.: "Target.Location.Latitude". The name of the type should be the one that gets marked, and what better universal marker for "typeness" than "_Type"? e.g.: Target : Target_Type; Location : Location_Type; Latitude : Latitude_Type; Before you all shudder at this, let me point out that this is just as readable "AS English" as anything else: I can read this off as "Target is an object of Target_Type",etc. (No, you're right, I don't win any points here, since as I argued above, _anything_ could be read off as English -- but at least I don't lose any points, either.) You can still tack modifiers onto your object names to distinguish them from each other: Enemy_Target, Friendly_Target : Target_Type; but now there's no ambiguity about whether those modifiers mark the identifiers as object names versus type names. If you did need to have more "specific" type names, you'd still use the same "type-marker": type Enemy_Target_Type is new Target_Type with ... type Friendly_Target_Type is new Target_Type with ... Enemy_Target : Enemy_Target_Type; Friendly_Target : Friendly_Target_Type; This scheme is quick, painless and "semantically economical." We can get past naming questions and get on with the business of programming. > The > reason is that your program will be more readable AS AN ENGLISH SEN- > TENCE. For example > > Error_Count : Natural; > > can be read as "Error_Count is a natural number". It could even be read > as "Error_Count: Natural". What about: type Error_Count_Type is range 0 .. Error_Limit; -- i.e., don't resort to using a predefined integer type -- if you can avoid it... Error_Count : Error_Count_Type; I only wish the original designers of Ada83 had clued into this style from the start. I find myself wishing Ada95 looked more like this: Integer : Integer_Type; Natural : Natural_Type; Float : Float_Type; Boolean : Boolean_Type; Character : Character_Type; String : String_Type; Duration : Duration_Type; ... generic type Object_Type (<>) is limited private; -- vs. "Object" type Pointer_Type is access Object_Type; -- vs. "Name" procedure Ada.Unchecked_Deallocation (Pointer : in out Pointer_Type); -- vs. "X" ... procedure Deallocate is new Ada.Unchecked_Deallocation (Object_Type => Target_Type, Object_Pointer_Type => Target_Pointer_Type); -- instantiations are more understandable this way, because -- you can tell at a glance that these parameters are types, -- and not, say, objects or subprograms ... Target_Pointer : Target_Pointer_Type := new Target_Type; ... Deallocate (Pointer => Target_Pointer); ... package Ada.Exceptions is ... type Exception_Identity_Type is ... -- vs. "Exception_Identity" ... procedure Raise_Exception (Exception_Identity : in Exception_Identity_Type; -- vs. "E" Message_String : in String_Type := ""); -- vs. "Message" ... end Ada.Exceptions; ... Target_Error : exception; Target_Not_Found_String : constant String_Type := "Selected target not found."; ... Ada.Exceptions.Raise_Exception (Exception_Identity => Target_Error'Identity, Message_String => Target_Not_Found_String); Alas, alas, what might have been ... :-) > Notice also, as the rationale to the naming > section of AQ&S says, it's Integer, Boolean, and Character, not Inte- > gers, Booleans, and Characters. Well, I agree with Charles that you should stick to the singular when naming objects and their types. You can look at a type declaration as a description of a "single" thing, but at an abstract level: "This isn't any particular object, but this is what any given object of this type would look like." What still remains, however, is what to do about packages. Here again, I've come to adopt Norman Cohen's scheme: Use the plural for a package name. E.g.: package Targets is type Target_Type is ... procedure Blow_Up (Target : in out Target_Type); ... The plural makes sense for a package name, because a package is a logical grouping of related declarations -- a package, if you will, is "about" a topic. Topics are often discussed in the plural: "This package is about "targets" -- how you declare them, and what operations you can do with them." The plural form in English is usually very close to the length of the singular, which is good because package names will be referenced frequently (if you avoid "use" clauses). Usually an English plural is just one character longer than the singular ("Target" vs "Targets"), or two characters longer ("Company" vs "Companies"), or occasionally shorter (!) though these are for words derived from Latin ("Datum" vs. "Data") or Greek ("Phenomenon" vs. "Phenomena"). (For cases like "Fish" vs. "Fish", "Moose" vs. "Moose", "Deer" vs. "Deer", etc., that problem will have to be solved by the legions of engineers developing real-time embedded code for the Department of the Interior, the Nature Conservancy, and Greenpeace ... ;-) ------------------------------------------------------------------------ Internet.Usenet.Put_Signature (Name => "John G. Volan", Home_Email => "johnvolan@sprintmail.com", Slogan => "Ada95: The World's *FIRST* International-Standard OOPL", Disclaimer => "These opinions were never defined, so using them " & "would be erroneous...or is that just nondeterministic now? :-) "); ------------------------------------------------------------------------