LFE Style Guide

10 Proper Forms

10.1 Defining Constants

As mentioned earlier, LFE has no form for defining constants. As such, simply define a function that takes no arguments and has the name of your constant:

(defun pi () 3.14)

10.2 Defining 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.

You should avoid excessive nesting of binding forms inside a function. If your function ends up with massive nesting, you should probably break it up into several functions or macros.

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 ...)

10.3 Conditional Expressions

Use a (when ...) guard if the checks being performed are simple logical operations or use the type-checking (is_*) BIFs.

Use (if ...) when there are two alternatives.

Use (cond ...) when there are more than two alternatives.

Use (case ...) when a single expression is being checked for several possible values.

You should prefer (and ...)/(andalso ...) or (or ...)/(orelse ...) when their use would produce more concise code.

10.4 Identity, Equality, and Comparisons

If you need to exactly match equal and not equal, you should use the forms (=:= ...) and (=/= ...).

If you don't need exactly equality (e.g., you want 42.0 and 42 to be considered the same), you should use the forms (== ...) and (/= ...).

10.5 Iteration

Unlike Common Lisp, LFE doesn't have forms for iteration such as DOLIST, DOTIMES, and LOOP.

LFE does support Erlang comprehensions, though, and can perform iterative tasks through those.

For more information on when to use iteration vs. recursion, see Chapter 7, Language Usage Guidelines of the LFE Style Guide, section 7.2, "Recursion".