Skip to content

Commit 5e5d0fc

Browse files
committed
add naming rules and examples
1 parent 76dd708 commit 5e5d0fc

File tree

1 file changed

+82
-17
lines changed

1 file changed

+82
-17
lines changed

README.md

+82-17
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ The goal of these conventions is to be concise, universal, and remarkable. It ta
2525
[Sort Args](#user-content-sort-arguments-and-limit-them-to-0--4-per-call)
2626
[Compose](#user-content-do-not-change-the-same-variable-in-steps-but-compose-once-from-parts))
2727
4. [**Naming**](#user-content-naming)  
28-
([Subprograms](#user-content-subprograms-procedurefunction)
29-
[Types](#user-content-types-classstructsubtypes)
30-
[Variables](#user-content-variables)
28+
([Pick One](#user-content-pick-one-word-for-one-concept)
29+
[Bools](#user-content-boolean-variablesfunctions-should-have-a-ishascan-prefix)
30+
[Subprograms](#user-content-naming-subprograms-procedurefunction)
31+
[Types](#user-content-naming-types-classstructsubtypes)
32+
[Variables](#user-content-naming-variables)
3133
[Word Pairs](#user-content-use-word-pairs-opposites-antonyms))
3234
5. [**Code Layout**](#user-content-code-layout)
3335
6. [**Documentation**](#user-content-documentation)  
3436
([Comments](#user-content-write-brief-comments-of-high-quality)
3537
[TODOs](#user-content-use-todo-and-fixme-tags)
3638
[Readmes](#user-content-write-readme-files)
37-
[Logging](#user-content-use-a-logging-library)
39+
[Logging](#user-content-avoid-print-use-a-library-with-log-levels)
3840
[File Headers](#user-content-write-file-headers-for-header-files)
3941
[Docstrings](#user-content-use-docstrings-for-public-apis))
4042
7. [**Languages**](#user-content-languages)  
@@ -185,7 +187,7 @@ There are two code smells that should remind you of this rule:
185187

186188
* **Copy & Paste:** Every time you take your mouse and mark lines with the intention to copy them, you are going to violate this rule. Instead of slightly adjusting copied lines, think about the common pattern between those lines and create a new function.
187189

188-
* **Repeated `if-else` and `switch-case` statements:** If you are testing the same conditions at different locations (e.g. state variables), you can abstract these differences with Polymorphism and the Strategy Pattern.
190+
* **Repeated `if-else` and `switch-case` statements:** If you are testing the same conditions at different locations (e.g. state variables), you can abstract these differences with Polymorphism and the [Strategy Pattern](https://refactoring.guru/design-patterns/strategy).
189191

190192

191193

@@ -219,7 +221,7 @@ if (speed > limit &&
219221
**Better ✔**
220222
```c
221223
MeterPerSecond limit = SPEED_LIMIT_NIGHT;
222-
drive(Point origin, Point dest);
224+
drive(Point origin, Point destination);
223225
224226
isNight = (T_NIGHT_MIN < t.h && t.h < T_NIGHT_MAX);
225227
isSpeeding = (limit < speed);
@@ -232,7 +234,26 @@ if (isSpeeding && isNight){ ... }
232234

233235
If the argument list of a subprogram grows too long, try to combine related arguments in a
234236
new data structure. For example, instead of passing `x`, `y`, `z`
235-
coordinates individually, use a single vector.
237+
coordinates individually, use a single vector.
238+
239+
240+
<table>
241+
<tr><td><strong>Bad ❌</strong></td><td><strong>Better ✔</strong></td></tr>
242+
<tr>
243+
<td>
244+
245+
```c
246+
makeCircle(double r, double x, double y)
247+
```
248+
249+
</td><td>
250+
251+
```c
252+
makeCircle(Point center, double radius)
253+
```
254+
255+
</td></tr></table>
256+
236257

237258

238259

@@ -285,33 +306,69 @@ Code should communicate behavior to other humans with lower complexity than the
285306
286307
287308
309+
### Pick one word for one concept.
310+
311+
Each concept should be described by a single word. Do not use `send()`, `write()`, and `transmit()` as synonyms for the same process, such as sending a message over a bus. Same holds true for `handleRequest()`, `processQuery()`, or `manageIncomingPacket()`.
312+
313+
Each word should only describe a single concept. Do not use `activate()` for setting a boolean variable and sending an activation packet to another system component. The first procedure is safe and instant, the second could fail, block execution, or run asynchronously. Better call it `sendActivationMsg()`.
314+
315+
288316
289-
### Subprograms (=Procedure/Function)
317+
318+
319+
320+
321+
### Boolean Variables/Functions should have a `is/has/can` prefix.
322+
Clean code reads like prose and these prefixes achieve clear and concise naming.
323+
There is no difference between the naming of variables, e.g. `hasElements`, and functions, e.g. `hasElements()`, except that functions can also answer true/false questions regarding arguments, such as `isFile(path)` or `user.hasAccessTo(file)`.
324+
325+
<!-- Variable Example: `hasElements`, `isUsingIO`<br>
326+
Function examples: `hasElements()`, `isFile(path)`, `user.hasAccessTo(file)` -->
327+
328+
* consider the slightly uncommon prefixes `can` to express abilities/possibilities, e.g. `canWalk`.
329+
* boolean names regarding [Collections](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)) should use `Each/Any` before the prefix, e.g. `isEachLightOn` / `isAnyLightOn`
330+
* prefer positive forms. Use `isActive` not `isInactive` to avoid confusing negations (`!isInactive`). Same for `hasElements` (not `isEmpty`) and `isEnabled` (not `isDisabled`).
331+
* Avoid further uncommon prefixes, such as `does`, `are`, `was`, `will`, `should`.
332+
333+
334+
| Rule | Bad ❌ | Better ✔ |
335+
|:---------------|:--------------------------------------------------|:------------|
336+
| Consider `can` | `isAllowedToWalk`, `hasWalkAbility`, `isWalkable` | `canWalk` |
337+
| Avoid `not` | `isNotEmpty`, `!isEmpty` | `hasElements` |
338+
| Avoid `are`: | `areAllLightsOn`, `isAllLightsOn` , `allLightsOn` | `isEachLightOn` |
339+
| Avoid `was/had`| `wasSend`, `hasBeenSent`, `hadArrived` | `isSent` |
340+
| Avoid `does` | `doesUseIO`, `mightUseIO` | `isUsingIO`, `canUseIO` |
341+
342+
343+
Fun fact: The old [jQuery 1.7](https://code.jquery.com/jquery-1.7.2.js) had a boolean called `doesNotAddBorder`. Now they use `isBorderBox`.
344+
345+
346+
347+
### Naming Subprograms (=Procedure/Function)
290348
291349
Procedures *may* return values, functions always return a value. Methods are subprograms of a class.
292350
* procedure names should start with a verb. e.g. `syncViews()`, `list.addItem(x)`.
293-
* function names should describe the result and, if suitable, its type. e.g. `time_ms(), sin(x)`
351+
* function names should describe the result and, if suitable, its type. e.g. `time_ms(), sin(x), isFile(path)`
294352
* class methods should not repeat or include the name of the class. Define `Line.length()`, not `Line.getLineLength()`
295353
296354
> ⚠ **Caution:** *Single noun subprograms should be pure functions! Never let e.g. `x.length()` change a state.*
297355
298356
299357
300-
### Types (=Class/Struct/Subtypes)
358+
### Naming Types (=Class/Struct/Subtypes)
301359
302360
* type names should be capitalized nouns. E.g. `Integer`, `Date`, `Line2D`
303-
* enums/structs are types and named as types without a special prefix/suffix.<br>
361+
* enums/structs are types and should be named as types without a special prefix/suffix.<br>
304362
E.g. `enum Color = {RED, GREEN, BLUE}`
305363
* interface names can start with a capital `I` and can also be adjectives. E.g. `IObservable`
306364
307365
308366
309-
### Variables
367+
### Naming Variables
310368
311369
* variables with a large scope *should* have long names, variables with a small scope *may* have short names [[CdCm]](#user-content-references).
312370
* collections (set, array, dict) should have a plural name. E.g. `cars`, `indices`
313371
* the prefix `n` or `num` should be used for names representing the total number of objects in a collection. E.g. `numCars`
314-
* boolean variables should start with a `is/has/can/does` prefix (e.g. `isEmpty`, `doesUseIO`).
315372
* write constant names in capitals. E.g `CFG_TEMPERATURE_MAX = 80.0`
316373
* prefix global variables with `g_`
317374
@@ -371,7 +428,11 @@ Noun and adjective pairs with same/similar length:
371428
</details>&nbsp;
372429

373430

374-
> **Avoid inappropriate terms:** Many organizations discourage the use of `master/slave` due to their negative association in different cultures. See [1](https://www.drupal.org/node/2275877) and [2](https://bugs.python.org/issue34605).
431+
432+
433+
434+
> **Avoid inappropriate terms:** Many organizations discourage the use of `master/slave` due to their negative association in different cultures. See [1](https://www.drupal.org/node/2275877) and [2](https://bugs.python.org/issue34605).<br>
435+
> **Avoid useless noise-terms:** E.g. `data`, `info`, `process`. What would be the difference between `Product`, `ProductData`, and `ProductInfo`?
375436
376437

377438

@@ -474,8 +535,8 @@ There are two different interest groups for your code, so please make sure that
474535
* **Developers:** How to compile. Module structure, dependencies, contribution rules, where to contact developers.
475536

476537

477-
### Use a Logging Library
478-
Provide meaningful logging messages at correct log levels:
538+
### Avoid `print`. Use a library with log levels.
539+
479540

480541
| Level | Use-case | Example |
481542
|:----------|-----------------------------------------------|----------------|
@@ -488,9 +549,10 @@ Provide meaningful logging messages at correct log levels:
488549
| Trace: | step-by-step implementation details | loop index |
489550

490551

552+
491553
* Each log entry should at least output log level and file/module name (or topic label). Timestamps and line numbers are optional.
492554
* Log with context and avoid messages like “Operation Failed” or “Write Complete”.
493-
* Separate parameters and messages.
555+
* Separate message (`"User connected"`) from parameters (`"ip=%s", ip`)
494556

495557

496558
<strong>Bad ❌</strong><br>
@@ -503,6 +565,9 @@ log.info("P2P: User connected. [id=%s, ip=%s]", uid, ip)
503565
```
504566

505567

568+
569+
570+
506571
### Write file headers for header files.
507572

508573
Each code file with interfaces (e.g. `.h` files in C) should start with a block comment that briefly explains what this module/class/lib does. However, do not provide author name or changelogs as this info belongs into the [Version Control System](https://www.geeksforgeeks.org/version-control-systems/).

0 commit comments

Comments
 (0)