| name | Common Lisp Ecosystem |
| description | This skill should be used when the user asks to "write common lisp", "CLOS", "ASDF", "defpackage", "defsystem", or works with Common Lisp, SBCL, or Coalton. Provides comprehensive Common Lisp ecosystem patterns and best practices. |
| version | 0.1.0 |
Provide comprehensive patterns for Common Lisp, CLOS, ASDF system definition, SBCL-specific features, and Coalton integration.
<common_lisp_fundamentals>
Code and data share the same syntax (homoiconicity). Enables powerful macro systems for code transformation.
First-class named objects used for identifiers. Interned in packages, can have value, function, and property list.
Functions can return multiple values using values, multiple-value-bind, multiple-value-list.
Special variables with dynamic scope using defvar/defparameter. Convention: *earmuffs* for special variables.
Common Lisp Object System - Generic functions and multiple dispatch
Define a class with slots. Slot options: :initarg, :initform, :accessor, :reader, :writer, :type, :documentation.
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age))
(:documentation "Represents a person."))
Define generic functions with multiple method implementations.
(defgeneric greet (entity)
(:documentation "Greet an entity."))
(defmethod greet ((p person))
(format t "Hello, a!%" (person-name p)))
Method qualifiers (:before, :after, :around) for aspect-oriented programming.
(defmethod greet :before ((p person))
(format t "Preparing to greet...~%"))
(defmethod greet :around ((p person))
(format t "[Start]%")
(call-next-method)
(format t "[End]%"))
Classes can inherit from multiple parent classes. Uses C3 linearization for method resolution order.
(defclass employee (person job-holder)
((employee-id :initarg :id :accessor employee-id)))
Common Lisp condition system - Restarts and handlers
Handle conditions similar to try-catch
(handler-case
(/ 1 0)
(division-by-zero (c)
(format t "Caught: ~a~%" c)
0))
Handle conditions without unwinding stack
(handler-bind
((error #'(lambda (c)
(format t "Error occurred: ~a~%" c)
(invoke-restart 'use-value 0))))
(restart-case
(error "Something went wrong")
(use-value (v) v)))
Define recovery points
(defun parse-entry (entry)
(restart-case
(parse-integer entry)
(use-value (v)
:report "Use a different value"
:interactive (lambda () (list (read)))
v)
(skip-entry ()
:report "Skip this entry"
nil)))
Define custom condition types for structured error handling.
(define-condition invalid-input (error)
((value :initarg :value :reader invalid-input-value))
(:report (lambda (c stream)
(format stream "Invalid input: ~a"
(invalid-input-value c)))))
Define packages with explicit dependencies and exports.
(defpackage #:my-project
(:use #:cl)
(:import-from #:alexandria #:when-let #:if-let)
(:export #:main
#:process-data))
Define local package nicknames for shorter, clearer references.
(defpackage #:my-project
(:use #:cl)
(:local-nicknames (#:a #:alexandria)
(#:s #:serapeum)))
Another System Definition Facility - Build system for Common Lisp
Basic ASDF system definition with metadata and component dependencies.
(defsystem "my-project"
:description "My project description"
:version "0.1.0"
:author "Author Name"
:license "MIT"
:depends-on ("alexandria" "cl-ppcre")
:components ((:file "package")
(:file "utils" :depends-on ("package"))
(:file "main" :depends-on ("utils"))))
Organize system components into modules for better structure.
(defsystem "my-project"
:components
((:module "src"
:components ((:file "package")
(:file "core" :depends-on ("package"))))
(:module "tests"
:depends-on ("src")
:components ((:file "test-suite")))))
Infer dependencies from defpackage forms for modern, maintainable systems.
(defsystem "my-project"
:class :package-inferred-system
:depends-on ("my-project/main"))
;; In my-project/main.lisp:
(defpackage #:my-project/main
(:use #:cl)
(:import-from #:my-project/utils #:helper))
Define test system with automatic test execution using test-op.
(defsystem "my-project/test"
:depends-on ("my-project" "fiveam")
:components ((:file "tests"))
:perform (test-op (o s)
(uiop:symbol-call :fiveam '#:run!
(uiop:find-symbol* '#:my-test-suite :my-project/test))))
Recommended directory layout for Common Lisp projects.
my-project/
├── my-project.asd
├── src/
│ ├── package.lisp
│ ├── utils.lisp
│ └── main.lisp
└── tests/
└── test-suite.lisp
Steel Bank Common Lisp - High-performance implementation
Create standalone executable with SBCL.
(defun main ()
(format t "Hello, World!~%")
(sb-ext:exit :code 0))
(sb-ext:save-lisp-and-die "my-app"
:toplevel #'main
:executable t
:compression t)
SBCL threading support with make-thread and mutex synchronization.
(defvar *result* nil)
(let ((thread (sb-thread:make-thread
(lambda ()
(setf result (heavy-computation)))
:name "worker")))
(sb-thread:join-thread thread))
;; Mutex
(defvar lock (sb-thread:make-mutex))
(sb-thread:with-mutex (lock)
(critical-section))
Call C functions from SBCL using sb-alien interface.
(sb-alien:define-alien-routine "strlen" sb-alien:int
(str sb-alien:c-string))
(strlen "hello") ; => 5
Use declarations for type information and optimization settings. Options: type, ftype, inline, optimize.
(defun fast-add (x y)
(declare (type fixnum x y)
(optimize (speed 3) (safety 0)))
(the fixnum (+ x y)))
SBCL-specific extensions for system interaction and performance tuning.
;; Command-line arguments
sb-ext:*posix-argv*
;; Execute external programs
(sb-ext:run-program "/bin/ls" '("-l"))
;; Trigger garbage collection
(sb-ext:gc)
;; POSIX interface: sb-posix
;; Network sockets: sb-bsd-sockets
Statically typed functional programming on Common Lisp
Define algebraic data types in Coalton with type-safe operations.
(coalton-toplevel
(define-type (Maybe a)
None
(Some a))
(declare safe-div (Integer -> Integer -> (Maybe Integer)))
(define (safe-div x y)
(if (== y 0)
None
(Some (/ x y)))))
Define type classes for polymorphic behavior in Coalton.
(coalton-toplevel
(define-class (Printable a)
(print-it (a -> String)))
(define-instance (Printable Integer)
(define (print-it x)
(into x))))
Coalton compiles to efficient Common Lisp code and is interoperable with regular CL.
Use coalton-toplevel for type-safe code sections
Coalton functions can call CL functions and vice versa
Provides Hindley-Milner type inference with type classes
<context7_libraries>
Available Context7 documentation libraries for Common Lisp ecosystem.
Common Lisp Docs - General Common Lisp documentation
/lisp-docs/lisp-docs.github.io
4.7
580
ASDF - Another System Definition Facility documentation
/websites/asdf_common-lisp_dev
7.5
190
SBCL - Steel Bank Common Lisp documentation
/sbcl/sbcl
8.0
86
CFFI - Common Foreign Function Interface documentation
/websites/cffi_common-lisp_dev
7.5
198
FiveAM - Testing framework documentation
/websites/fiveam_common-lisp_dev
7.5
164
Coalton - Statically typed functional programming documentation
/coalton-lang/coalton
6.6
568
Use resolve-library-id then get-library-docs for latest documentation.
;; Get ASDF documentation
mcp__context7__get-library-docs
context7CompatibleLibraryID="/websites/asdf_common-lisp_dev"
topic="defsystem"
<common_patterns>
Resource management with unwind-protect for cleanup.
(defmacro with-open-socket ((var host port) &body body)
`(let ((,var (make-socket ,host ,port)))
(unwind-protect
(progn ,@body)
(close-socket ,var))))
Loop macro for iteration with collection, filtering, and accumulation.
(loop for item in list
for i from 0
when (evenp i)
collect item into evens
finally (return evens))
Common format directives: ~a (aesthetic), ~s (standard), ~d (decimal), ~f (float), ~% (newline), ~{~} (iteration), ~[~] (conditional).
(format t "~a is ~d years old~%" name age)
Document functions with docstrings explaining purpose and parameters.
(defun my-function (arg)
"Docstring describing the function.
ARG is the argument description."
(process arg))
<best_practices>
Use *earmuffs* for special variables
Use +plus-signs+ for constants
Prefer functional style, minimize mutation
Provide restarts for recoverable situations
Document exported symbols
Use appropriate condition types, not just error
Use check-type for argument validation
Prefer ASDF package-inferred-system for new projects
Consider Qlot for per-project dependency management
Use Roswell for portable script execution
</best_practices>
<modern_tooling>
Per-project dependency manager (like bundler/npm)
<use_case>Install dependencies from qlfile</use_case>
<use_case>Run commands with project dependencies</use_case>
qlot install
qlot exec ros run
Lisp implementation manager and script runner
Install Lisp implementations or libraries
Start REPL with specified implementation
Build standalone executable
ros install sbcl
ros run
ros build myapp.ros
<anti_patterns>
Global mutable state makes code harder to test and reason about.
Pass state explicitly or use closures to encapsulate mutable state.
Using :use for packages other than :cl creates namespace pollution.
Use :import-from or package-local-nicknames for clearer dependencies.
Ignoring conditions loses error context and recovery opportunities.
Handle conditions with handler-case or handler-bind, and provide appropriate restarts.
Deeply nested code reduces readability and maintainability.
Extract helper functions and use early returns to reduce nesting depth.
Using eval in application code is slow and defeats compile-time optimization.
Use macros for compile-time code generation or first-class functions for runtime dispatch.
Custom reader macros make code harder to read for others.
Use reader macros sparingly and document them clearly when necessary.