§ 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")