Unlike most other languages, Elm doesn’t use syntactic markers such as curly brackets, parentheses, or semicolons to specify code boundaries. It uses whitespaces and indentations instead. There are situations where if we don’t place our code in a certain order or provide proper indentation, Elm will throw a syntax error. Let’s go through those one by one.
Function Definitions
Let’s use an example from the Function section earlier in this chapter to understand the implications of using incorrect orders and indentations when defining a function.
All Elm files begin with a module
definition. It’s perfectly fine to add comments above the module
definition, but no other code can go above it.
import
lines are optional. If they’re included, they’re listed right below the module
definition. Both module
and import
lines must start at the left most column. The top-level function definitions are placed below the import
lines. They too must start at the left most column. Later, you will be introduced to other concepts in Elm such as type
that also go below the import
lines.
Notice how two blank lines are used to separate the definitions of escapeEarth
and main
functions? Because Elm doesn’t use delimiters such as curly braces to surround functions like in other mainstream languages, using only a single blank line to separate definitions can make our code less readable.
Elm borrowed this convention from Python — another great language. However, the module
and import
lines are separated with only one blank line. These spacing rules are enforced by elm-format
. It is a little confusing that elm-format
uses two blank lines between some definitions, and one blank line between others. Maybe that will change by the time 1.0.0
version is out.
At the time of this writing, elm-format
uses four spaces to indent a function body. Because it’s still in beta, don’t be surprised if it ends up using two spaces instead of four when version 1.0.0
is out.
In the earlier sections, you were led to believe that the body of a function, if
, let
, and case
expressions must be indented with at least one space. That still holds true. Syntactically speaking, all Elm cares about is an indentation with at least one space, but using more than one space improves readability of our code.
Note: If you’re interested in further exploration, here is a vigorous debate between the Elm community members on whether to use two or four spaces for indentation. We programmers are so nitpicky, aren’t we?
If, Let, and Case Expressions
An if
expression must be placed inside a function definition, otherwise Elm will throw an error.
The part after then
and final else
should be placed on the next line indented with four spaces. It’s perfectly fine to place an if
expression inside a let
or case
expression as long as they themselves are placed inside a function. We already saw an example of this in the Let Expression section earlier. Here it is again.
The code inside the let
area must be indented with at least one space, whereas the code inside the in
area doesn’t need any indentation. The body of the case
expression must also be indented with at least one space. As of this writing, elm-format
uses four spaces in both cases to improve readability. The list below summarizes the indentation rules we have covered thus far.
- Basic Indentation Rules
-
module
,import
, and top-levelfunction
definitions must start at the left most column.- If an expression is split into multiple lines, the code that is part of that expression must be indented under that expression with at least one space.
- Parts of the expression that are grouped together should be indented with equal number of spaces. This rule is particularly important in the
let
area.