LFE Programming Rules and Conventions
7 Specific Lexical and Stylistic Conventions
7.1 Don't write deeply nested code
Nested code is code containing, for example, case
/if
/receive
statements within other case
/if
/receive
statements. It is bad
programming style to write deeply nested code - the code has a tendency to
drift across the page to the right and soon becomes unreadable. Try to limit
most of your code to a maximum of two levels of indentation. This can be
achieved by dividing the code into shorter functions.
7.2 Don't write very large modules
A module should not contain more than 400 lines of source code. It is better to have several small modules than one large one.
7.3 Don't write very long functions
Don't write functions with more than 15 to 20 lines of code. Split large function into several smaller ones. Don't solve the problem by writing long lines.
7.4 Don't write very long lines
Don't write very long lines. A line should not have more than 80 characters. (It will for example fit into an A4 page.)
7.5 Variable names
Choose meaningful variable names - this is very difficult.
If a variable name consists of several words, use "-" to separate them.
Example: my-variable
.
Avoid using "" as don't care variable, use variables beginning with ""
instead. Example: _name
. If you at a later stage need the value of the
variable, you just remove the leading underscore. You will not have problem
finding what underscore to replace and the code will be easier to read.
7.6 Function names
The function name must agree exactly with what the function does. It should
return the kind of arguments implied by the function name. It should not
surprise the reader. Use conventional names for conventional functions (
start
, stop
, init
, main-loop
).
Functions in different modules that solves the same problem should have the
same name. Example: my-module:module-info
.
Bad function names is one of the most common programming errors - good choice of names is very difficult!
Some kind of naming convention is very useful when writing lots of different functions. For example, the name suffix "?" or "p" (the latter from Common Lisp) could be used to signify that the function in question returns the atom true or false.
(...?) -> 'true | 'false
(...p) -> 'true | 'false
Similarly, the prefix check
should return tuples whose first elements
indicate the success or failure of the check:
(check-...) -> #(ok ...) | #(error ...)
7.7 Module names
Erlang, and thus LFE, has a flat module structure (i.e. there are not modules within modules, no concept of real, native packages). Often, however, we might like to simulate the effect of a hierarchical module or package structure. This can be done by giving the same prefix to sets of related modules.
If, for example, an ISDN handler is implemented using several different but related modules, the modules should be given names such as:
(defmodule isdn-init ...)
(defmodule isdn-partb ...)
(defmodule isdn-...)
7.8 Format programs in a consistent manner
A consistent programming style will help you, and other people, to understand your code. Different people have different styles concerning indentation, usage of spaces etc.
LFE programs should follow Common Lisp formatting and style conventions. These are discussed in more detail in the LFE Style Guide, though we well make a few points here.
Peter Norvig and Kent Pitman's Lisp style guide (1993) lists some excellent maxims of good style, which we repeat here:
- Be explicit
- Be specific
- Be concise
- Be consistent
- Be helpful by anticipating the user's needs
- Be conventional (not obscure)
- Build usable abstractions
- Allow tools to interact