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:

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.