langston-barrrett.github.io
Programming Style Guide
This is my personal style guide for writing code. As with all style guides, this guide is incomplete, fallible, and its recommendations aren't appropriate for every circumstance.
I've only recently started writing this, so it's obviously particularly incomplete. Hopefully, it will grow as I learn and think more!
This guide is focused only on recommendations that apply to the majority of programming languages I use (such as Haskell or Python). I have more specific guides for language- or paradigm-specific recommendations (see e.g. my Python style guide).
Its intended audience is intermediate or advanced programmers who endeavor especially to write reliable, correct code. But to be honest, I mostly publish this so I have somewhere with thorough explanations that I can point people to when I make comments during code reviews.
This document aspires to confirm to my Meta Style Guide.
Do you have ideas for this guide? Contact me!
Formatting
I often use an automatic code formatter like Black or YAPF for Python. When that's not an option, I tend to follow these recommendations on formatting code. Formatting is mostly not very important, but there are a few goals that I think are worth considering:
- Uniformity: Having some universal choices about formatting makes codebases subjectively more readable, and reduces the number of decisions you have to make when writing code.
- Speed of reading, writing, and editing code.
- Minimizing diffs: This is helpful for focused code review, and when reviewing git history to understand a regression. See e.g. Use Trailing Commas.
These goals are not usual crucial, so the following recommendations are quite "soft"/low priority.
Expressions in the Upper Left
You may consider formatting expressions such that the syntax that begins the expression appears in the upper left-hand corner of the smallest box containing the expression.
Examples
In Haskell, it's common to write expressions using do
-notation
like this:
foo = do
bar
baz
This is inconsistent with this recommendation, so I would write the above like so:
foo =
do bar
baz
Justification
This is just for consistency and uniformity: it gives a general guideline if you're unsure of how you might decide to format a given expression.
Indentation Shouldn't Depend on Identifiers
The indentation of a line shouldn't depend on the length of any identifier in your program.
Examples
In Haskell, it's possible to write expressions using do
-notation
like this:
foo = do bar
baz
Using the above style, the indentation of baz
depends on the name
foo
. So if you later choose to rename foo
to quux
, you'll
have to re-indent baz
(and all subsequent lines). I would instead
write the above like so:
foo =
do bar
baz
Similarly, I would write this:
data Foo = Foo
{ bar :: Int
, baz :: Bool
}
instead like this:
data Foo
= Foo
{ bar :: Int
, baz :: Bool
}
Justification
This is for speed and minimizing diffs: You shouldn't have to re-indent a bunch of lines that don't contain a given identifier when that identifier changes.
Use Trailing Commas
Use trailing commas on multi-line datastructures.
Example
Instead of:
numbers = [
8,
2,
13
]
Write:
numbers = [
8,
2,
13,
]
Justification
This minimizes diffs. If you add something after the last element, the only line that appears in the diff is the one you added.