[Ada Information Clearinghouse]

Ada '83 Quality and Style:

Guidelines for Professional Programmers

Copyright 1989, 1991,1992 Software Productivity Consortium, Inc., Herndon, Virginia.

CHAPTER 3: Readability

3.2 Naming Conventions

Choose names that clarify the object's or entity's intended use. Ada allows identifiers to be any length as long as the identifier fits on a line with all characters being significant (including underscores). Identifiers are the names used for variables, constants, program units, and other entities within a program.

Language Ref Manual references: 2.3 Identifiers, 4.1 Universal Expressions

In this section...
3.2.1 Names
3.2.2 Type Names
3.2.3 Object Names
3.2.4 Program Unit Names
3.2.5 Constants and Named Numbers
Summary of Guidelines from this section


3.2.1 Names

guideline

example

In a tree-walker, using the name Left instead of Left_Branch is sufficient to convey the full meaning given the context. However, use Time_Of_Day instead of TOD.

Mathematical formulas are often given using single-letter names for variables. Continue this convention for mathematical equations where it would recall the formula; for example:
A*(X**2) + B*C.

rationale

A program that follows these guidelines can be more easily comprehended. Self-documenting names require fewer explanatory comments. Empirical studies have shown that you can further improve comprehension if your variable names are not excessively long (Schneiderman 1986, 7). The context and application can help greatly. The unit of measure for numeric entities can be a source of type names.

note

See Guideline 8.1.2 for a discussion on how to use the application domain as a guideline for selecting abbreviations.

Language Ref Manual references: 3.1 Declarations


3.2.2 Type Names

guideline

example

type Day is 
   (Monday,    Tuesday,   Wednesday, Thursday,  Friday, 
    Saturday,  Sunday);
    
type Day_Of_Month    is range      0 ..    31; 
type Month_Number    is range      1 ..    12; 
type Historical_Year is range -6_000 .. 2_500;

type Date is 
   record 
      Day   : Day_Of_Month; 
      Month : Month_Number; 
      Year  : Historical_Year; 
   end record;

In particular, Day should be used in preference to Days or Day_Type;

The identifier Historical_Year might appear to be specific, but it is actually general, with the adjective, historical, describing the range constraint.

rationale

When this style and the suggested style for object identifiers are used, program code more closely resembles English (see Guideline 3.2.3). Furthermore, this style is consistent with the names of the language's predefined identifiers. They are not named Integers, Booleans, Integer_Type, or Boolean_Type.

However, using the name of a type from the predefined packages is sure to confuse a programmer when that type appears somewhere without a package qualification.

Language Ref Manual references: 3.3 Types and Subtypes, 8.6 The Package Standard, 14.3.10 Specification of the Package Text_IO


3.2.3 Object Names

guideline

example

Nonboolean objects:
Today           : Day; 
Yesterday       : Day; 
Retirement_Date : Date;

Boolean objects:
User_Is_Available : Boolean;        -- predicate clause 
List_Is_Empty     : Boolean;        -- predicate clause 
Empty             : Boolean;        -- adjective 
Bright            : Boolean;        -- adjective

rationale

Using specific nouns for objects establishes a context for understanding the object's value, which is one of the general values described by the (sub)type's name (Guideline 3.2.2). Object declarations become very English-like with this style. For example, the first declaration above is read as "Today is a Day."

General nouns, rather that specific, are used for record components because a record object's name will supply the context for understanding the component. Thus, the following component is understood as "the year of retirement.":
Retirement_Date.Year

Following conventions which relate object types and parts of speech makes code read more like text. For example, because of the names chosen, the following code segment needs no comments:
if List_Is_Empty then 
   Number_Of_Elements := 0; 
else 
   Number_Of_Elements := Length_Of_List; 
end if;

note

If it is difficult to find a specific noun that describes an object's value during the entire execution of a program, the object is probably serving multiple purposes. Multiple objects should be used in such a case.

Language Ref Manual references: 3.2 Objects and Named Numbers, 3.5.3 Boolean Types


3.2.4 Program Unit Names

guideline

example

The following are sample names for elements that comprise an Ada program.

Sample procedure names:
procedure Get_Next_Token          -- get is a transitive verb 
procedure Create                  -- create is a transitverb

Sample function names for boolean-valued functions:
function Is_Last_Item             -- predicate clause 
function Is_Empty                 -- predicate clause

Sample function names for nonboolean-valued functions:
function Successor                -- common noun 
function Length                   -- attribute 
function Top                      -- component

Sample package names:
package Terminal is               -- common noun 
package Text_Utilities is         -- common noun

Sample task names:
task Terminal_Resource_Manager is -- common noun that shows action

Below is a sample piece of code to show the clarity that results from using these conventions the parts-of-speech naming conventions.
Get_Next_Token(Current_Token);

case Current_Token is 
   when Identifier =>         Process_Identifier; 
   when Numeric    =>         Process_Numeric; 
end case;  -- Current_Token

if Is_Empty(Current_List) then 
   Number_Of_Elements := 0; 
else 
   Number_Of_Elements := Length(Current_List); 
end if;

When packages and their subprograms are named together, the resulting code is very descriptive.
if Stack.Is_Empty(Current_List) then 
   Current_Token := Stack.Top(Current_List); 
end if;

rationale

Using these naming conventions creates understandable code that reads much like natural language. When verbs are used for actions, such as subprograms, and nouns are used for objects, such as the data that the subprogram manipulates, code is easier to read and understand. This models a medium of communication already familiar to a reader. Where the pieces of a program model a real-life situation, using these conventions reduces the number of translation steps involved in reading and understanding the program. In a sense, your choice of names reflects the level of abstraction from computer hardware toward application requirements.

note

There are some conflicting conventions in current use for task entries. Some programmers and designers advocate naming task entries with the same conventions used for subprograms to blur the fact that a task is involved. Their reasoning is that if the task is reimplemented as a package, or vice versa, the names need not change. Others prefer to make the fact of a task entry as explicit as possible to ensure that the existence of a task with its presumed overhead is recognizable. Project-specific priorities may be useful in choosing between these conventions.

Language Ref Manual references: 6.1 Subprogram Declarations, 6.5 Function Subprograms, 7.2 Package Specifications and Declarations, 9.1 Abort Statements, 9.5 Entries, Entry Calls, and Accept Statements, 12.1 Generic Declarations, 12.3 Generic Instantiation


3.2.5 Constants and Named Numbers

guideline

example

3.141_592_653_589_793                 -- literal 
Max : constant Integer := 65_535;     -- constant 
Pi  : constant         := 3.141_592;  -- named number 
PI / 2                                -- static expression 
PI                                    -- symbolic value

Declaring Pi as a named number allows it to be referenced symbolically in the assignment statement below:
Area :=       Pi * Radius**2;       -- if radius is known.

instead of
Area := 3.141_59 * Radius**2;       -- Needs explanatory comment.

Also, ASCII.Bel is more expressive than Character'Val(8#007#).

Clarity of constant and named number declarations can be improved by using
other constant and named numbers. For example:
Bytes_Per_Page   : constant := 512; 
Pages_Per_Buffer : constant := 10; 
Buffer_Size      : constant := Pages_Per_Buffer * Bytes_Per_Page;

is more self-explanatory and easier to maintain than
Buffer_Size : constant := 5_120;   -- ten pages

The following literals should be constants:
if New_Character  = '$' then  -- "constant" that may change 
... 
if Current_Column = 7 then    -- "constant" that may change

rationale

Using identifiers instead of literals makes the purpose of expressions clear reducing the need for comments. Constant declarations consisting of expressions of numeric literals are safer since they do not need to be computed by hand. They are also more enlightening than a single numeric literal since there is more opportunity for embedding explanatory names. Clarity of constant declarations can be improved further by using other related constants in static expressions defining new constants. This is not less efficient because static expressions of named numbers are computed at compile time.

A constant has a type. A named number can only be a universal type: universal integer or universal real. Strong typing is enforced for identifiers but not literals. Named numbers allow compilers to generate more efficient code than for constants and to perform more complete error checking at compile time. If the literal contains a large number of digits (as Pi in the example above), the use of an identifier reduces keystroke errors. If keystroke errors occur, they are easier to locate either by inspection or at compile time.

Linear independence of literals means that the few literals that are used do not depend on one another and that any relationship between constant or named values is shown in the static expressions. Linear independence of literal values gives the property that if one literal value changes, all of the named numbers of values dependent on that literal are automatically changed.

note

There are some gray areas where the literal is actually more self-documenting than a name. These are application-specific and generally occur with universally familiar, unchangeable values such as the following relationship:
Fahrenheit := 32.0 + (9.0 * Celsius) / 5.0;

Language Ref Manual references: 2.4 Numeric Literals, 2.5 Character Literals, 2.6 String Literals, 3.2 Objects and Named Numbers, 4.9 Static Expressions and Static Subtypes, A. Predefined Language Attributes


Back to document index