Lisp Functions – Optimal Order for Defining Functions

common-lisplisp

In which order should code in a single lisp file be organised? Is there any common style guideline that allows other lisp programmers to easily understand code?

Googling for lisp style guideline yields plenty results; among them:

However, non appear to discuss how functions and other definitions should be organised within a single source file.

"Clean Code" by Martin Fowler (which is not specifically targeted at Lisp) recommends organising functions/methods top to bottom: first describing the code abstractly and next delving deeper and deeper into details. Which is in my opinion a good way to organise function definitions.

However, when the function definitions are ordered top to bottom, the SBCL REPL gives caught STYLE-WARNING: undefined function: … when loading a lisp file. So apparently SBCL thinks using a function before defining it is bad style.

What is the best practice for the order of definitions? Preferably without resulting in compiler/interpreter warnings.

Best Answer

For Common Lisp I'm using something like this:

  • files are organized in systems and subsystems (see for example ASDF as a tool for that)
  • you can put everything in one file, but that takes some care
  • larger pieces of Lisp are organized in systems of files (see above) and are usually compiled with the file compiler
  • using compile-file, a file is a compilation unit

Files in a system:

  1. system declaration(s)
  2. package declaration(s)
  3. utility functions
  4. macros
  5. classes
  6. various code
  7. machine/os/implementation specific code
  8. a system for tests

a subsystem in a file:

  1. editor header (mode, package, dialect, text encoding, base, ...)
  2. copyright, license
  3. purpose and usage description
  4. using which package
  5. global configuration vars / data
  6. constants
  7. main classes
  8. condition classes
  9. macros and their support code
  10. generic functions / methods / functions
  11. examples

If you develop, you load the compiled system developed so far and extend it incrementally. Once a new functionality is written and tested -> compile the system again, load it and test it again.

The old book 'Lisp: Style and Design' by Molly M. Miller and Eric Benson describes organizing principles and gives an example. Since this book is old, there is some newer infrastructure and some new tools. But the general principles mentioned in the book are still useful.

Related Topic