Code Naming
The purpose of a name is to enable users to correctly identify its target. Do not aim for the shortest name or one that is only natural at the declaration site. Preserve the meaning required at actual reference sites, and remove only words that are already clear there.
1. Investigate the context
Before creating, reviewing, or renaming anything, confirm the information needed to make a judgment within the relevant scope.
- Existing repository conventions, naming constraints imposed by the target language or framework, and neighboring names
- The target's responsibilities, actual values or behavior, and concepts that must be distinguished within the same hierarchy
- Representative reference sites and import / export patterns, not just the declaration site
- Whether the name forms part of an external contract, such as a public API, schema, persisted data, CLI, or file path
2. Evaluate the name
Choose a name using the minimum amount of information needed to satisfy the following criteria.
- Meaning: The behavior, role, or domain concept should be clear. Do not conceal meaning behind purely abstract terms.
- Distinctiveness: The name should not be confused with another target in the same scope or usage context.
- Redundancy: Do not repeat information that is already obvious from the namespace, receiver, type, or path at the usage site. However, do not assume that a path visible at the declaration site is also visible at every reference site.
- Consistency: Use the same terminology for the same concept, and follow the repository's and language's conventions for case, plurals, abbreviations, and suffixes.
- Stability: Base the name on the responsibility that should be maintained, rather than on a temporary implementation approach or location.
Do not shorten a name if doing so would force readers to trace types, implementation sources, or conversation history. A short local variable is acceptable when it is unambiguous in context, but a public name should be understandable on its own.
3. Judge by target type
- Files and directories: Words already evident from the parent path may be omitted, but preserve distinction from neighboring elements and readability after moving the file or directory. Do not arbitrarily change names specified by the language or framework, such as , , or .
- Functions and methods: Represent the actual operation, transformation, or side effect. Do not repeat meaning already supplied by the receiver or namespace. Do not mechanically accept vague names such as or .
- Types, constants, and variables: Prioritize the role and semantic distinctions. Do not mechanically remove or prohibit names such as , , , or type-name suffixes.
- Actions, schemas, and serialization keys: Distinguish internal identifiers from names referenced or persisted by external systems. Changing an externally referenced or persisted name constitutes a contract change.
4. Use counterexamples to refine judgments
workspaceBackgroundToGridStyle
in
src/workspace/background.ts
is a candidate for redundancy, but
is not always better.
ts
// It can be shortened when the namespace is visible at the reference site
background.toGridStyle(input);
// It must retain its meaning when directly imported without a namespace
backgroundToGridStyle(input);
On the other hand, changing
to
may make the name indistinguishable from multiple creation operations. Always consider cases where declining to shorten the name is the correct decision.
5. When renaming
- Enumerate the names to be changed and their actual references, and target only changes that clearly improve meaning. Do not perform unrelated bulk shortening.
- Prefer symbol-aware rename features provided by language servers, and avoid ambiguous string replacement. When changing paths, check imports, case-sensitive / case-insensitive filesystems, and build configuration.
- Align all affected references, including types, schemas, tests, fixtures, documentation, and generated sources. Use string searches such as for discovery and confirmation of leftovers, but not as the sole evidence that all references have been covered.
- In principle, preserve names used by public APIs, persisted keys, databases, events, and external integrations. If a change is necessary, investigate its impact on users and existing data, and handle compatibility through explicit migrations, aliases, codecs, or other appropriate mechanisms. Do not change a wire name merely because an internal identifier has been shortened.
- Select formatter / typecheck / lint / test / contract validation defined by the project according to the change, then reread the affected reference sites to confirm that the names have improved.
Completion criteria
- Ambiguity has been reduced at reference sites without losing necessary distinctions.
- There are no inconsistencies or leftovers between references and names.
- External / persisted contracts have either been preserved, or the changes and migrations have been made explicit.
- Verification evidence is appropriate to the scale of the change.
Do not perform a rename when its improvement cannot be explained. Limit the report to the primary changes, compatibility impact, and verification results.
Supporting references
For detailed conventions specific to a language, prioritize the languages and frameworks adopted by the project. References:
- Google TypeScript Style Guide — Naming: Redundant information in types and clarity of identifiers
- Google Go Style — Naming: Adjusting the amount of information according to the usage scope and surrounding context
- Rust API Guidelines — Naming: Rust naming conventions and terminology that expresses transformations