I recommend capitalizing the first letter of every word, and, optionally, capitalizing every letter of an acronym. My rationale for rejecting the two other popular styles, firstWordLowerCase and allwordslowercase are as follows:
firstWordLowerCase allows you to save one shift-key depression, but the automatic capitalization feature of the QDL editor makes this rather less important.
I wish to emphasize that I am not an advocate of the "hungarian" notation used by Windows, where every single variable variable name is prefixed with a couple of seemingly pseudo-random letters. In my view prefixes are only necessary to convey information that would take a person significant effort to discover otherwise.
For example, I advocate prefixing global variable names with "g". Suppose a person is looking at the code for a member function someone else has written. For an object-oriented language, it is natural to assume that a variable is either local or a member of the same class of the function in which the reader sees the variable. If this is not the case, and no prefix is used, the reader has to, at least, check the preceding lines of the function and the class definition to determine that the variable is global. Now, if the program uses global variables to any significant degree but does not follow this convention, then the reader may be forced to check nearly every variable, even the class-specific ones, to confirm that they aren't global.
Hungarian notation mainly attempts to convey the type of a variable with the prefix letters. There are several reasons why this is not necessary or is undesirable:
This is not to say that conveying the type of a variable is not useful. However, hungarian notation is not the way it should be conveyed. Instead, the name itself should suggest a type, as well as what the variable might be used for. The meaning of a variable name can and should rely on the context of its usage. For example:
It is arguable that programmers are too inept at doing this, and so a company hungarian-notation policy might be the only way to "make sure" coders create readable code. However, such a policy would be difficult to enforce, and some programmers may be just as inept at grasping hungarian notation (and memorizing the company-specific prefix codes) than said other programmers are at making decent names. Besides, variable names need to convey not only type but purpose, usage, etc.
In cases where conveying variable type is important, using a consistently spelt abbreviation of the type name works well. This abbreviation can be put anywhere in the name that sounds best when the code is read allowed. For example, you may decide that Str denotes a String. Then, a collection of strings used as some kind of dictionary might be called StrDictionary and some command encoded as a string might be called CommandStr. However, such an abbreviation is only needed when the name and general context is not sufficient. For example, it would usually be obvious that FirstName and LastName is a string, so you need not call it LastNameStr. On the other hand, in some algorithm where FirstName and LastName are the first and last indexes into an array of name strings, it would be helpful to instead call the variables FirstNameIndex and LastNameIndex, or perhaps FirstIndex and LastIndex, to differentiate from the more typical usage of FirstName and LastName. Notice that the term Index works better than a hungarian prefix such as n because it suggests not only the data type (number) but also the usage (as an array index).
Another common place where abbreviations are necessary is in naming user interface objects. For example, if you have a UI element named PrintRange, it could easily be a group box, a text box, or a slider. In fact, you might have all three types of controls on one dialog box, all printing-range related. This is one time where I'll admit that even a hungarian prefix system is helpful.
But the bottom line is, programmers should be expected to use their intelligence to decide upon names, to make a prefix scheme unnecessary 90+% of the time.
Notwithstanding the above, I do suggest prefixes and naming conventions that convey information that is not obvious through other means. For example, a name, even a good long one, typically does not convey scope or storage class. Therefore, I suggest the following conventions for QDL programs:
Here are some conventions I would recommend against:
There is a more meaningful distinction, and that is between something that is part of an object's essence and something to which the object merely links. For example, in a sound object that has the ability to play itself, a sound driver object would be something the object links to, as opposed to something that is part of the sound. But this is a matter of problem-space semantics, not solution-space semantics. If a prefix were to be used, it should map to the problem-space semantics. Whether the sound driver object is actually accessed through a reference, or embedded in the sound object is irrelevant; the problem space suggests using a reference (to "link" to the sound driver), but it is conceivable that a coder might directly embed an object representing a sound driver directly into the sound object.
In any event, the line between "linking to" and "being a part of" is often a blurry one, and prefixes are best reserved for clear-cut properties.
Since a prefix is already used to indicate global variables, the other possibilities are:
That a variable is local should be emphasized by placing local variable declarations near where the variable is used in code, and by using short functions (so that the variable declaration and usage of that variable are on the same page).
As discussed above, Automatic variables should be limited to obviously temporary and index variables, so that it is clear that the variable is local.
Thus, by a simple process of elimination, the reader can quickly determine that a variable is a member of the current class, rather than a local or global variable. A prefix is unnecessary. (In a With block, any given identifier may be a member of the current class or the other class. In that case the prefix convention would not help, since the members of both classes would have the same prefix.)
There are two basic types of functions:
Accessor functions (public functions which simply return the value of private variables) are examples of property functions: functions which are primarily concerned with retrieving information. Such a function is typically used like a variable and its name should reflect this. Therefore, property functions should be named in noun form, e.g. BestMatch, Width, Time, etc.
Manipulation functions, meanwhile, make things happen, and so should be named in verb form, e.g. SetWidth, DrawGraph, OpenFile.
The C++/Java practice of naming all functions in verb form is discouraged, as it emphasizes the difference between variables and functions, even though in many cases a function and a variable are logically interchangeable (such as the Width property of a bitmap.) Besides, it requires you to type Get in front of all accessors, which annoys the multitudes of abbreviation-loving programmers, who think typing NumberOfElementsInArray() is too much of a drag already. The use of Get may be justified if an information retrieval requires significant action to be taken or CPU time to be used, making it inappropriate to treat it like a variable access. Often there are better words to suggest this, though, such as Find or Retrieve.
In type naming, it is paramount that names present as much information as possible and that the naming convention is consistent. In the sections above on variable naming, the rules have been fairly lax. Because variable names are typically repeated over and over in code, programmers want them to have short names, and redundant prefix conventions are burdensome. When I say long variable names are okay, I mean relative to the 3 to 6 character names most coders love. Because type names are typically used less often, what is lacking in variable names should be made up for in type names.
When someone reading code cannot see the purpose of a variable by its context, the next thing (s)he will do is look for the variable declaration. Conversely, some code readers will start trying to understand code by first going to its declarations and gleaning information from them. In either case, it is important that the variable declaration tells as much as possible about the variable.
Consistency in type naming is paramount, more so than for variable naming. If you don't use these conventions consistently, you'll either end up confusing the reader or forcing him (her) to find the declaration of the type to figure out the stuff the conventions should have conveyed. I'm much more supportive of prefix conventions on type names than variable names*.
* For those things the language does not convey directly. That is, I still dislike conventions such as the one used by Windows to convey pointer types: prefixing with "P" and/or "LP", because the language already had a method of conveying this ("*"). Same goes for the "C" used to mean "Const".
Note: None of this lessens the need for proper comments to provide more information and clarification!
QDL supports unusual characters in class names to allow spaces between words in class names, and to allow symbols to help describe the purpose of a class. Take advantage of this.
Sometimes a class name may involve an acronym (because expanding the acronym would make the name too long.) For example, the class name Device Independent Bitmap is rather long (not to mention impossible for half of programmers to spell!) and may be abbreviated as DIB. However, DIB may mean nothing to someone not familiar with Windows bitmaps, so a word may be expanded to hint at the meaning. In this case it is probably best to not use a space, so the class would be named DIBitmap.
What is in a variable declaration? Often, just two things: the variable name, the class name. Because type names need be written less frequently than variable names, it is less burdensome to make a long type name. The variable name is typically going to be short, rarely more than two words, and may likely use abbreviations. Therefore, your type names should compensate by being more verbose. They shouldn't be ridiculously long, of course, and may need to use abbreviations too, but don't be surprised if they reach 15 characters or more. Prefixes are okay for class names, and even recommended, provided that they are used with consistency. Here are some suggestions:
The status of any class as "primitive" is an important part of its identity, and should be reflected in the name. Often, a class is created that is just an alias for a numeric type. Using aliases is a good way to convey purpose, but when you create these aliases you need to make it clear that the new class is really just a number. The same goes for enumerations and strings. The distinction between each of these is usually important too, so I suggest a separate convention for each:
Enumerations
Although enumerations (and the numerical types from which they derive) are technically classes, they are usually used for very different purposes than other classes. Therefore, it is important, when a person is looking at a declaration, to be able to tell when the variable being created is an enumeration. Unfortunately, the basic name of an enumeration often does not convey this fact; therefore, I suggest that you prefix enumeration class names with "E".
This section suggests a number of abbreviations to shorten oft-used words. It is not important that you abbreviate your words, but if you do, I recommend that you not use the following abbreviations for anything but the words given here. It is best not to abbreviate any word four letters or less, or abbreviate to save only one character. For example, abbreviating To as 2 is bad style.
| Table of Contents | Qwertie's Site/Mirror |
|