Source-Code Formatting

Learn about formatting of Elixir code.

We'll cover the following

The Elixir core team wanted to standardize the format of source code that was submitted to them for inclusion in the various Elixir core projects. They made it easy for submitters by including a source-code formatting tool in Elixir 1.6. This tool is pretty smart. It knows not only the syntax of Elixir but also the parse tree, meaning that it’ll often move things between lines, drop commas, add parentheses, and so on.

This is done using the mix format command. It can format single files, directory trees, and whole projects (see mix help format for information). This formatting replaces the files it touches, so we should make sure to check in before running it.

Let’s have a look at some before-and-after formatting.

Use of formatting

What happens if we feed it untidy code?

def no_vowels string 
  do
    string |>
      String.replace(~r/[aeiou]/, "*")
    end

    def separator(column_widths) do 
  map_join(column_widths, "-+-", fn width ->
 List.duplicate("-", width)  
end)
  end

The formatter tidies it nicely:

def no_vowels(string) do 
  string
  |> String.replace(~r/[aeiou]/, "*") 
end

def separator(column_widths) do   
  map_join(column_widths, "-+-", fn width ->
    List.duplicate("-", width) 
  end)
end

It’s also pretty smart about multiline constructs:

  @names [
Doc, Grumpy, Happy,
  Sleepy, Bashful, Sneezy,
      Dopey
]

This produces the following:

This produces:
@names [ 
  Doc,
  Grumpy,
  Happy,
  Sleepy,
  Bashful,
  Sneezy,
  Dopey
]

Here, because the original split onto a new line, the formatted result was normalized into one element per line.

There’s lots to like about the formatter. However, it destroys some elements of the layout that we might want to keep. For example, some programmers like to line things up vertically. This is easy to read and maintain. Most editors have support for this:

options = %{
style: "light", background: "green"
}

They also have support for this:

name = "Alphabet"
url = "https://abc.xyz" 
entry_count = 10

Unfortunately, the Elixir formatter goes to some trouble to remove that extra space, producing the following:

options = %{
style: "light", background: "green"
}

name = "Alphabet"
url = "https://abc.xyz" 
entry_count = 10

Then there’s the contentious trailing comma.

When we list things out, we put a comma after each item and put each item on a new line. This makes it easier to move things around, add new items, sort the list, and so on. Each line is just like the other: the first and last lines aren’t special.

plugins = [
  Format,
  Index,
  Print, 
]

The formatter thinks this is silly and removes the comma.

plugins = [
  Format,
  Index,
  Print 
]

And finally, there’s the trailing comment. Sometimes, we use short comments inside a block of code and add them to the end of the line.

def format(template, 
  bindings,
  options ) do
  # ...
end

This isn’t the best example, but even so, the formatter makes some unfortunate decisions:

def format( 
      template,
      # the bindings to use
      bindings,
      # :verbose | :narrow
      options 
     ) do
   # ...
end

Some of this comes down to personal preference. If you like what it does, or if you’re submitting code to a project that requires it, use the formatter.

Get hands-on with 1400+ tech skills courses.