Naming Conventions#
Caution
This guide has been based on LSST’s C++ API documentation guide. Please respect the creators and contributor of the original guide as they have done an external work.
General Limitations#
Warning
Identifiers should consist of English words. Other languages, jargons, jokes or abuses are forbidden.
The fundamental quantity being described should appear first in the name, with modifiers concatenated afterward. A rule of thumb is to ask what the units of the quantity would be, and make sure that quantity appears first in the name.
dateObs
, notobsDate
for a quantity that fundamentally is a date/time of significance.timeObsEarliest
(or,timeObsFirst
), notearliestObsTime
.
Use care to select the most meaningful name to represent the quantity being described
imageMean
notpixelMean
if we are talking about the mean value of an image, not repeated measurements of a pixel.
Names should not explicitly include units
skyBackground
notskyADU
to indicate the sky background level.expMidpoint
rather thantaiMidPoint
.timeRange
nottaiRange
.
Abbreviations#
Abbreviations in names SHOULD be avoided.
computeAverage(); // NOT: compAvg();
There are two types of words to consider. First are the common words listed in a language dictionary. These must never be abbreviated. For example, write:
command
instead ofcmd
;copy
instead ofcp
;point
instead ofpt
;compute
instead ofcomp
;initialize
instead ofinit
.
Then there are domain specific phrases that are more naturally known through their abbreviations/acronym. These phrases should be kept abbreviated. For example, write:
html
instead ofHypertextMarkupLanguage
;cpu
instead ofCentralProcessingUnit
;ccd
instead ofChargeCoupledDevice
.
Acronyms, Initialisms, Alphabetisms#
In English abbreviations have been written with a full stop/period/point in place of the deleted part to show the ellipsis of letters, although the colon and apostrophe have also had this role. Such punctuation is diminishing with the belief that the presence of all-capital letters is sufficient to indicate that the word is an abbreviation. But, in code, identifiers with acronyms in all-capital letters style are much less readable. That is why we propose to keep using pascal style for acronyms.
For example we choose DomObject instead of DOMObject (where DOM is Document Object Model).
// Use this
enum class Enum
{
Sfinae
};
// Instead of this
enum class Enum
{
SFINAE
};
Uppercase acronyms are not allowed for enumerators too.
// Use this
enum class Enum
{
Sfinae
};
// Instead of this
enum class Enum
{
SFINAE
};
This rule concerns only established acronyms, initialisms and alphabetisms. Moreover such things should be used sparingly, and limited to very common usages in the relevant community.
Warning
Remember, using of your own acronyms, initialisms or alphabetisms is forbidden.
This means that obscure abbreviations should be avoided too: clarity is probably more important than brevity.
apertureDiam
would be better thanapDia
Booleans#
Names for boolean variables and methods SHOULD be obviously boolean.
Examples of good names include:
bool isSet, isVisible, isFinished, isFound, isOpen;
bool exists();
bool hasLicense(), canEvaluate(), shouldSort()
Common practice in the C++ development community and partially enforced in Java.
Using the is
prefix can highlight a common problem of choosing bad boolean names like status
or flag
.
isStatus
or isFlag
simply doesn’t fit, and the programmer is forced to choose more meaningful names.
Negated boolean variable names MUST be avoided.
bool isError; // NOT: isNoError
bool isFound; // NOT: isNotFound
The problem arises when such a name is used in conjunction with the logical negation operator as this results in a double negative.
It is not immediately apparent what isNotFound
means.
Complement names#
Complement names MUST be used for complement operations, as this reduces complexity by symmetry.
For example:
get/set
,add/remove
,create/destroy
,start/stop
,insert/delete
,increment/decrement
,old/new
,begin/end
,first/last
,up/down
,min/max
,next/previous
,old/new
,open/close
,show/hide
,suspend/resume
,etc..
Shorternings#
It is recommended to use well-known abbreviations of given domain instead of their full equivalents. Use of one- or two-letter identifiers and shortenings in words is forbidden with exception of worldwide known. However developer (and maintainer) should be consistent in one module bounds.
Examples of allowed shortenings are shown in tables below (list is not closed).
Shortering |
Meaning |
---|---|
i, j, k, idx |
Loop counters, Index |
x, y |
Coordinates |
e, ex |
Exception |
init |
Initialize |
it, itEnd, it* (itObject, itValues) |
Iterator |
p, *Ptr (pObject, EntityPtr) |
Pointer |
ref, *Ref (objectRef, valuesRef) |
Reference |
id |
Identifier |
opt, *Opt, opt* (optObject, EntityOpt) |
Optional |
Identifiers#
Scope Designation#
Names of local and non-constant static variables, class members, function and template arguments are prepended with prefix that designates scope.
Scope |
Prefix |
Example |
---|---|---|
Local variable |
None |
|
Static constant variable |
|
|
Static non-constant variable |
|
|
Static |
|
|
Function parameter |
_ |
|
Template type parameter |
|
|
Template value parameter |
|
|
Class field |
m_ |
|
Class static field |
ms_ |
|
Global variable |
g_ |
|
Methods and Functions#
It is recommended to use predefined naming schemes for common actions. Predefined naming schemes can be found below. However if your method name can’t be fit into those schemes, there are some rules that can help you.
Names representing methods or functions SHOULD naturally describe the action of the method (and so will usually start with a verb).
Names for methods that return new objects MAY start with past-tense verbs.
It is sometimes useful to pair a mutator with a
const
method that returns a mutated copy of the callee. When it is, the imperative verb in the name of the mutator MAY be changed to the past tense to make the distinction clear. For example:Box b; b.dilateBy(a); // b is modified Box c = b.dilatedBy(a); // a modified copy of b is assigned to c
Methods for creating new objects#
Naming Scheme |
Example |
Description |
---|---|---|
create* |
EntityPtr createEntity();
std::unique_ptr<Node> createNode();
|
Method that creates entity objects (e.g. factory methods). Usually return object and do not save it internally. Should be used in most cases. |
build*, make*, provide* |
SearcherPtr provideSearcher();
|
Method creates utility objects. Can be used to distinct methods within scope (class). Prefix create* can be used if you prefer. |
clone* |
ObjectPtr clone();
|
Clone method (as exception from create*). |
Methods for returning objects#
Naming Scheme |
Example |
Description |
---|---|---|
get* |
Object const & getObject() const;
|
Method returns non-null object by reference. if object is not present by some reasons, should throw an exception. Should have O(1) complexity. |
tryGet* |
Object const * tryGetObject() const;
|
Method returns pointer to object that not always exists. Returned pointer must always be non-owning. |
take* |
Object const & takeObject() const;
|
Method returns non-null non-constant object by reference. Prefer this method to overloaded version of get* method. |
tryTake* |
Object const * tryTakeObject() const;
|
Method returns by non-constant pointer object that not always exists. Prefer this method to overloaded version of tryGet* method. Returned pointer must always be non-owning. |
find* |
Object const * findObject() const;
Object * findObject();
|
Method searches object and returns optional value (pointer or Method should have O(1)* or O(logN) complexity. Returned pointer must always be non-owning. |
Methods for returning statuses/flags/props#
Naming Scheme |
Example |
Description |
---|---|---|
is* |
bool isActive() const;
bool isPort() const;
|
Method answers questions like: * is an object of a specific kind/type? * has it some state (full, initialized, etc)? Should have O(1) complexity. |
has* |
bool hasChildren() const;
|
Method answers if object has a certain props. |
are* |
bool areEqual(...);
bool Class::equalsTo(...) const;
|
Comparison methods. Use either free function with 2 (or more) parameters. Second form should be used in case of class method. |
get* |
int getSize() const;
|
Methods returns values of some props or flags. |
Methods for modifying objects#
Naming Scheme |
Example |
Description |
---|---|---|
set* |
void setName(...);
void setMatched();
|
Method modifies single or several props. |
reset* |
void resetDesign(...);
void resetDesign();
|
Method can act in two ways: #. cleans props in case of empty parameters, #. or modifies props with new values passed to method. |
add* |
Object const & addObject(...);
void addObject(Object const &);
|
Method creates new object, saves to internal collection. And finally return reference to newly created object. Or method just adds already created object to internal collection. |
ensure* |
Node const & ensureNode(...);
|
Same as add*, but used to explicitly point that cache is used. Cache can be used to avoid duplicates or to optimize algorithm. If object with same properties already exist, it will be returned. No new instance will be created in this case. |
try* |
void tryEmplace(...);
|
Method performs action that fails (relatively) often. The fallback function call might be followed after failure. |