Skip to content

Lisp - Defining System

In modern Common Lisp, a system is a collection of source files that constitute a library or an application. ASDF (Another System Definition Facility) is the de facto standard tool for defining these systems, managing their components, and handling dependencies. Think of an ASDF file (.asd) as the equivalent of a Cargo.toml in Rust or a package.json in Node.js.

You define a system by creating a file named your-system-name.asd. This file contains a Lisp form that uses asdf:defsystem to declare metadata and components.

;;;; my-library.asd
(asdf:defsystem #:my-library
:description "A brief description of my new library."
:author "Your Name <you@example.com>"
:license "MIT"
:version "0.1.0"
:serial t ; Ensures components are loaded in the order they are listed.
;; Declare other systems this library depends on.
;; ASDF will ask Quicklisp to fetch them if they aren't available.
:depends-on (#:alexandria
#:drakma)
;; Define the files and modules that make up the system.
:components ((:file "packages") ; Often the first file, defines packages.
(:file "utils")
(:file "main")))
  • :description, :author, :license, :version: Standard metadata for your project.
  • :depends-on: A list of other ASDF systems your project needs. This is fundamental for dependency management.
  • :components: A list of the parts of your system. The most common types are :file (for a single .lisp file, without the extension) and :module (for a subdirectory containing more components).
  • :serial t: A convenience option that tells ASDF to compile and load the components in the exact order they appear in the :components list. This is very common for simpler systems.

A typical Common Lisp project follows a standard directory layout:

my-library/
├── my-library.asd ; The system definition file
├── README.md
├── LICENSE
├── packages.lisp ; Defines the package(s) for the system
├── main.lisp ; Main source code
└── utils.lisp ; Utility functions

Quicklisp is the standard library manager for Common Lisp. It works hand-in-hand with ASDF. While you can use ASDF directly, the modern workflow is to use Quicklisp, which will in turn use ASDF to build and load your system and its dependencies.

To load a local project you are working on, you must first ensure Quicklisp knows where to find it. The easiest way is to place your project folder inside ~/quicklisp/local-projects/. Once it’s there, you can load it from your REPL:

;; Load your system (and its dependencies) into your Lisp image.
(ql:quickload :my-library)

Quicklisp will find my-library.asd, parse it, download any dependencies listed in :depends-on if necessary, and then ask ASDF to compile and load all the component files in the correct order.

  • Standardization: ASDF provides the universal ‘project file’ format for Common Lisp, making it easy for others to use your code.
  • Dependency Management: Seamless integration with Quicklisp for automatic fetching and loading of required libraries.
  • Automatic Compilation: ASDF tracks file changes and recompiles files only when necessary, speeding up your development workflow.
  • Portability: An ASDF-defined system can be loaded and used by any developer on any major Common Lisp implementation (like SBCL, CCL, etc.).

ASDF can also be configured to run your project’s test suite. This typically involves adding a :test-op to your system definition and using a testing framework like FiveAM or Parachute.

;; Once configured, you can run your tests like this:
(asdf:test-system :my-library)