Decrease net cognitive complexity for developers.
The rules in this guide are intended to work well with the following assumptions:
Developers read code more than they write code, and internal developers write code more than outside collaborators:
- Readability > Writeability
- Writeability for internal developers > Writeability for outside collaborators
Developers have medium–large displays:
- Long lines are less likely to wrap
Developers use GitHub:
- Side-by-side line diffs are 119 characters long
Developers use VSCode:
- Auto-formatting, auto-linting, and code completion reduces keystrokes
[!] Indicates that a rule is controversial.
TODO: Fill me out
TODO: Fill me out
Do use a friendly and informal tone. Other rules follow from this one, such as using contractions.
Do use contractions.
# ✓ Good
def panic():
# Panic if we can’t recover from an error.# ✗ Bad
def panic():
# Panic if we cannot recover from an error.Do use curly single and double quotes instead of straight quotes.
// ✓ Good
let race; // “Xel’Naga”, “Terran”// ✗ Bad
let race; // "Xel'Naga", "Terran"Do use the ellipses character instead of 3 dots.
// ✓ Good
let series; // 1, 2, 3, …, 10// ✗ Bad
let series; // 1, 2, 3, ..., 10Do use an en dash when appropriate such as for spans and ranges.
// ✓ Good
let duration; // 2–3 weeks// ✗ Bad
let duration; // 2-3 weeks, 2 to 3 weeksDo use an em dash when appropriate such as replacing commas, parentheses, or colons.
// ✓ Good
let sentence; // Lorem ipsum — foo bar — dolor.// ✗ Bad
let sentence; // Lorem ipsum -- foo bar -- dolor.// ✓ Good
let symbols; // ←, →
let angle; // 45°// ✗ Bad
let symbols; // <-, ->
let angle; // 45 degreesDo use the canonical spelling of proper nouns.
# ✓ Good
words # Python, Node.js, PostgreSQL# ✗ Bad
words # python, node, postgresDo begin type descriptions with an indefinite article (“a/an”).
SQL:
-- ✓ Good
COMMENT ON TABLE unit IS 'A unit.';-- ✗ Bad
COMMENT ON TABLE unit IS 'The unit.';GraphQL:
# ✓ Good
type Unit {
"""A unit."""
}# ✗ Bad
type Unit {
"""The unit."""
}Do begin type property descriptions with a definite article (“the”) when applicable.
SQL:
-- ✓ Good
COMMENT ON COLUMN unit.name IS 'The name of a unit.';-- ✗ Bad
COMMENT ON COLUMN unit.name IS 'A name of a unit.';GraphQL:
# ✓ Good
type Unit {
name: String
"""The name of a unit."""
}# ✗ Bad
type Unit {
name: String
"""A name of a unit."""
}python:
# ✓ Good
class Unit:
name: str # The name of a unit.# ✗ Bad
class Unit:
name: str # A name of a unit.Comments should explain intent rather than what the code is doing. If it’s unclear what the code is doing then it should be refactored.
Do show examples when possible.
js:
// Get a unit’s globally unique identifier.
//
// (“Zumwalt-class destroyer”, 3) → “Unit:ZumwaltClassDestroyer:3”
// (“Leopard 2A7”, 5) → “Unit:Leopard2a7:5”
const getUnitId = (name: string, index: number) => `Unit:${pascalCase(name)}:${index}`;Do follow all writing style rules when also writing comments.
// ✓ Good
// e.g. “John Doe” → “john_doe”
const toKebabCase = () => {};// ✗ Bad
// e.g. "John Doe" => john_doe
const toKebabCase = () => {};Do use sentence case in comments.
py:
# ✓ Good
# Use Manhattan distance because it performs better on high dimensional data
distance = scipy.spatial.distance.cdist(tensor_a, tensor_b, metric='cityblock')# ✗ Bad
# use manhattan distance because it performs better on high dimensional data
distance = scipy.spatial.distance.cdist(tensor_a, tensor_b, metric='cityblock')js:
// ✓ Good
// Choose a background color that matches the sky
const backgroundColor = "#2ebde5"; // Azure/* eslint-disable capitalized-comments */
// ✗ Bad
// choose a background color that matches the sky
const backgroundColor = "#2ebde5"; // azureDo use punctuation on block comments.
py:
# ✓ Good
# Lorem ipsum dolor sit amet.
placeholder_text = …# ✗ Bad
# Lorem ipsum dolor sit amet
placeholder_text = …
# ✗ Bad
# Lorem ipsum dolor sit amet
# Consectetur adipiscing elit
placeholder_text = …Do punctuate comments that serve as documentation. These comments often generate Website docs, CLI arguments, etc.
@dataclass
class FetchBananasResponse
"""The API response for fetching bananas."""
banana_list: List[Banana]
"""A list of varying length bananas."""
@dataclass
class Banana:
"""An irresistible fruit loved by all the great apes."""
is_ripe: bool
"""Whether it is ready for eating."""
length: float
"""The length in meters."""# ✓ Good
speed = … # Meters per hour
time = … # Minutes
distance = speed / (time / 60) # MetersFollow the casing conventions of the current language.
json:
{
"boundingBox": [0, 0, 10, 10]
}python:
bounding_box = [0, 0, 10, 10]rust:
let bounding_box: [i32; 4] = [0, 0, 10, 10];typescript:
const boundingBox = [0, 0, 10, 10];Do favor readability to brevity.
# ✓ Good
docker_image = "huggingface/transformers-pytorch-gpu"
ec2_instance_type = "p3.8xlarge"# ✗ Bad
image = "huggingface/transformers-pytorch-gpu"
type = "p3.8xlarge"Do group related variables with a prefix.
# ✓ Good
cnn_kernel = (3, 3)
cnn_stride = (1, 1)
learning_rate = 1e-05# ✗ Bad
kernel = (3, 3)
stride = (1, 1)
learning_rate = 1e-05Do insert a space before postfixes and after prefixes.
# ✓ Good
hidden_layer_0 = "…"
hidden_layer_1 = "…"# ✗ Bad
hidden_layer0 = "…"
hidden_layer1 = "…"// ✓ Good
const userName = "…";
const userPassword = "…";// ✗ Bad
const username = "…";
const userPassword = "…";Don’t use abbreviations. They’re more likely to encounter naming conflicts. They must also be be learned and memorized.
# ✓ Good
directory = "data/units"
unit_direction = "NORTH"# ✗ Bad
dir = "data/units"
unit_dir = "NORTH"# ✓ Good
result, error = action()
response = request()# ✗ Bad
res, err = action()
res = req()# ✓ Good
sagemaker = SageMaker()
hyperparameters = {…}# ✗ Bad
sm = SageMaker()
hparams = {…}Do use acronyms and initialisms. They’re well known and less verbose. Moreover, the words they represent are often unknown; so must be learned and memorized
# ✓ Good
nato_classification = "cosmic"
radar_range = 1_700_150 # meters# ✗ Bad
north_atlantic_treaty_organization_classification = "cosmic"
radio_detection_and_ranging_range = 1_700_150 # meters# ✓ Good
s3_bucket = "secret-stuff"
website_url = "https://spear.ai"# ✗ Bad
simple_storage_service_bucket = "secret-stuff"
website_uniform_resource_locator = "https://spear.ai"Don’t invent acronyms or initialisms unless external users would find it easier to use. They’re not well known; so must be learned and memorized.
# ✓ Good
aerial_unit_direction = (0.8, 0.45)
aerial_unit_speed = 329# ✗ Bad
au_direction = (0.8, 0.45)
au_speed = 329# ✓ Good
rcn_has_attention = True
rcn_hidden_layer_size = 40# ✗ Bad
really_cool_network_has_attention = True
really_cool_network_hidden_layer_size = 40Do add type hints. Many names are ambiguous and can be confused for booleans, dates, functions, etc.
python:
# ✓ Good
created_date = "1776-07-04T04:56:02.000Z"
was_published = True# ✗ Bad
created = "1776-07-04T04:56:02.000Z"
published = Truetypescript:
// ✓ Good
fileBuffer = await fs.readFile("…");
isLoaded = false;// ✗ Bad
file = await fs.readFile("…");
loaded = false;Do differentiate types. It’s hard to switch between contexts when variable names represent different types.
# ✓ Good
url = "https://spear.ai"
parsed_url = urlparse("https://spear.ai")
# ✓ Good
agent_id = "10"
agent = Agent(id="10", type=Tiger)# ✗ Bad
url = "https://spear.ai"
url = urlparse("https://spear.ai")
# ✗ Bad
agent = "10"
agent = Agent(id="10", type=Tiger)Don’t add type definitions.
Reasons:
- They add superfluous information
- They increase refactoring costs
- They decrease portability
# ✓ Good
age = 21
confidence = 0.9# ✗ Bad
age_int = 21
confidence_float = 0.9// ✓ Good
const balance = BigInt(7_301_985);
const mask = new Uint8Array();// ✗ Bad
const bigIntBalance = BigInt(7_301_985);
const maskUint8Array = new Uint8Array();Do use appropriate boolean verbs.
# ✓ Good
can_delete = True
has_feature = True
should_reset = True# ✗ Bad
is_deletable = True
features = True
reset = TrueDo be positive with boolean variables.
python:
# ✓ Good
is_enabled = True
is_visible = False# ✗ Bad
is_disabled = False
is_not_visible = Truetsx:
// ✓ Good
<Tab isActive>Click me</Tab>// ✗ Bad
<Tab isInactive={false}>Click me</Tab>Do use the correct tense.
if was_suspended and not is_suspended:
print("Welcome back!")¶ 9W.fY: DON’T pluralize collections [!]
Don’t pluralize collections. Instead, specify the collection type.
Some object names are already plural. Therefore, it’s impossible to name a collection of those objects. Moreover, Uncountable nouns can’t be pluralized.
Specifying the collection type also clarifies which operations are allowed.
For example, a List can be appended or prepended to. Whereas, a Set can be added or removed from.
# ✓ Good
equipment_list = [{…}, {…}, …, {…}]
equipment = equipment_list[0]
# ✓ Good
settings_map = {"0": {…}, "1": {…}, …, "n": {…}]
settings = settings_map["0"]
# ✓ Good
id_list = ["0", "1", "2", "0"]
id_list.append("2")
id_set = set(id_list)# ✗ Bad
equipment = [{…}, {…}, …, {…}]
equipment = equipment[0]
# ✗ Bad
settings = {"0": {…}, "1": {…}, …, "n": {…}]
settings = settings["0"]
# ✗ Bad
ids = ["0", "1", "2", "0"]
ids.append("2")
distinct_ids = set(ids)# ✓ Good
curl https://api.spear.ai/user
curl https://api.spear.ai/user/5# ✗ Bad
curl https://api.spear.ai/users
curl https://api.spear.ai/users/5-- ✓ Good
SELECT * FROM person
SELECT * FROM person_address-- ✗ Bad
SELECT * FROM people
SELECT * FROM people_addressesDegrees are easier to reason about. Moreover, Radians serialize poorly because they are based on the irrational number π.
// ✓ Good
const turnLeft = (angle: number) => (360 + (angle - 90)) % 360;
turnLeft(0); // ⇒ 270// ✗ Bad
const turnLeft = (angle: number) => (2 * Math.PI + (angle - 0.5 * Math.PI)) % (2 * Math.PI);
turnLeft(0); // ⇒ 4.71238898038469Exception: A series of Math functions that require radians.
# ✓ Good
print(f"heading {heading}°")
print(f"{latitude}°, {longitude}°")# ✗ Bad
print(f"heading {heading}")
print(f"{latitude}, {longitude}")// ✓ Good
const successHexColorCode = "#297c3b";
const failureHexColorCode = "#ca3214";// ✗ Bad
const successRgbColorCode = "rgb(41, 124, 59)";
const failureRgbColorCode = "rgb(202, 50, 20)";Exception: A library requires another format. Exception: Manipulation is easier in another format. (e.g. HSL)
// ✓ Good
const color = "#ff0000";
const colorAlpha = "#ff0000ff";// ✗ Bad
const color = "#f00";
const colorAlpha = "#f00f";// ✓ Good
const backgroundColor = "#edf6ff";
const foregroundColor = "#006adc";// ✗ Bad
const backgroundColor = "#EDF6FF";
const foregroundColor = "#006ADC";# ✓ Good
type ClassLabel {
id: ID!
hexColorCode: HexColorCode
}# ✗ Bad
type ClassLabel {
id: ID!
color: HexColorCode
}-- ✓ Good
SELECT id, hex_color_code FROM class_label-- ✗ Bad
SELECT id, color FROM class_label