§ Common Lisp Cheat Sheet
- Peter Norvig's common lisp guide
- To make a runnable file, add
;; #!/usr/bin/env sbcl --script
to the top. - To change package, use ", set package"
- Good starting kit:
(declaim (optimize (speed 0) (safety 3) (debug 3)))
(defpackage :rasterizer1 (:use :common-lisp))
- Paredit cheat sheet
- SLIME tutorial
- First thing to do:
slime-sync-package-and-default-directory
( C-c ~
) to setup package and cwd
. - SLIME + parinfer + SBCL is quite a pleasant emacs lisp experience.
- LISPY-mode interface: eval expr (
e
), jump to definition ( F
), go back ( D
) - SLIME debugger: abort(
a
), continue( c
), quit( q
), goto frame source ( v
), toggle frame details ( t
), navigate next/prev frame( n
, p
), begin/end ( <
, >
), inspect condition ( c
), interactive evaluate at frame ( :
) - SLIME REPL: send expr to repl(
C-c C-y
), switch to repl ( C-c C-z
), eval last expr ( C-x C-e
), trace ( C-c C-t
) - SMILE REPL debug: trace (
C-c C-t
). Write (break)
in code and then run expression to enter debugger, step into ( s
), step over ( x
), step till return ( o
), restart frame ( r
), return from frame ( R
), eval in frame ( e
) - SLIME compile: compile whole file (
C-c C-k
), eval defun ( C-c C-c
), trace ( C-c C-t
). - SIME docs: lookup on hyperref (
C-c C-d h
) - SLIME goto: edit definition (
M-.
), come back ( M-,
). Find all references ( M-?
) - TODO: consider Sly rather than SLIME?
- SLIME repl options: set current working directory (
,!d
), set package ( ,push-package
). Alternatively, execute (swank:set-default-directory "/path/to/desired/cwd/")
- SLIME Restart:
M-x slime-restart-inferior-lisp
, or call (progn (unload-feature 'your-lib) (load-library "your-lib"))
- SLIME force re-evaluation of
defvar
, use M-x slime-eval-defun
( C-M-x
) . - Serepeum library for exhaustiveness checking
- Alexandria
destructuring-case
for pattern matching - Sycamore for purely functional data structures
- Screamer for logic programming
§ Entertaining footgun: let
bindings
(defgeneric errormsg (x))
(let* (x (errormsg 12)) x)
The above silently compiles, with an SBCL error:
This should clue you in that something terrible has happened.
The correct form of the let*
requires ONE outer paren
group to denote bindings, and ANOTHER paren for each key-value
pair.
So this should have been written:
(let* (
(x (errormsg 12))
) ...
But has been written as:
(let* (
x
(errormsg 12)
) ... )
This gets interpreted as:
(let* (
(x nil)
(errormsg 12)
) ... )
The takeaway appears to be that SBCL
warnings
ought to be treated as errors.
§ ASDF: treat warnings as errors:
(setf asdf:*compile-file-warnings-behaviour* :error)
§ Toys
Special variables (Mutable globals) should be surrounded by asterisks. These are called earmuffs. (defparameter positions (make-array ...))
(assert (condition)
(vars-that-can-be-edited))
(defun divide (x y)
(assert (not (zerop y))
(y)
"Y can not be zero. Please change it")
(/ x y))
(ql:quickload "str")