Credits: Google Common Lisp Style Guide, Emacs 21.2 Manual, Strandh’s Tutorial on Indentation, Rainer Joswig, ACow_Adonis, following Reddit users: defunkydrummer, lispm, KaranasToll, kazkylheku, theangreymacsshibe, xach, zulu-inoe
Lisp is infamous for its reliance on parentheses ( ) to delimit code and is notorious for being difficult to read because of this. As many experienced lisp programmers have pointed out, and as this article will hopefully show, properly indented code makes reading lisp much easier and the parentheses disappear into the background.
In this article, we will discuss some basic concepts for formatting Lisp code and I will share with you my personal notes, as a professional designer of presentations and reports. I hope you find it useful and that it makes it easier for you to read, write and enjoy lisp code.
Lisp code should be formatted according to the following guidelines.
Indent your code the way a properly configured GNU Emacs does. In practise, this means relying on a lisp editor (such as Emacs) that indents code automatically.
Aligned with the first argument
; if the first argument is on its own line, it is aligned with the function nameIndented two spaces
Indented four spaces
;; Align arguments to a function with the first argument:
(my-function arg-one
arg-two
arg-three)
;; Or under the function name:
(my-function
arg-one
arg-two
arg-three)
;; Body should be nested two spaces:
(when something
(do-this)
(and-this)
(and-also-this))
;; Distinguished forms should be nested four spaces:
(with-slots (a b)
distinguished-form
(print a)
(print b))
When an lisp form does not fit on one line, consider inserting newlines between the arguments so that each one is on a separate line. However, do not insert newlines in a way that makes it hard to tell how many arguments the function takes or where an argument form starts and ends.
;; Bad:
(do-something first-argument second-argument (lambda (x)
(frob x)) fourth-argument last-argument)
;; Good:
(do-something first-argument
second-argument
#'(lambda (x) (frob x))
fourth-argument
last-argument)
Always space elements like this: (+ (1 2) 3) and never like this (+(1 2)3) or (+ ( 1 2 ) 3).
Always put ending parentheses on the last line, and not seperately on a newline. Lisp programmers read code by indentation and not by parentheses so we do not need to allocate extra lines for closing parentheses.
;; Good:
(defun our-equal (x y)
(or (eql x y)
(and (consp x)
(consp y)
(our-equal (car x) (car y))
(our-equal (cdr x) (cdr y)))))
;; Bad:
(defun our-equal (x y)
(or (eql x y)
(and (consp x)
(consp y)
(our-equal (car x) (car y))
(our-equal (cdr x) (cdr y))
)
)
)
We should keep one blank line between top-level forms, unless they relate to definitions that are related to each other, e.g.:
;; Good:
(defun function-one
...)
(defun function-two
...)
;; Bad:
(defun function-one
...)
(defun function-two
...)
;; This is okay:
(defvar font "Arial")
(defvar bg-color "Black")
(defvar text-color "White")
(defvar font-size "12pt")
#code #programming #programming-languages #lisp