- Peter Norvig's common lisp guide
- To make a runnable file, add
;; #!/usr/bin/env sbcl --scriptto the top. - To change package, use ", set package"
- Good starting kit:
;; to change package, goto SLIME, type `,` for `, set package`.(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 andcwd. - 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, useM-x slime-eval-defun(C-M-x) . - Serepeum library for exhaustiveness checking
- Alexandria
destructuring-casefor 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:
;; caught STYLE-WARNING:;; The variable ERRORMSG is defined but never used.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* ( ;; <- OPEN pairs of bindings (x (errormsg 12)) ) ... ;; <- CLOSE bindingsBut has been written as:
(let* ( x (errormsg 12) ) ... )This gets interpreted as:
(let* ( (x nil) ;; notice the `nil` introduction (errormsg 12) ) ... )The takeaway appears to be that SBCL warnings
ought to be treated as errors.
§ ASDF: treat warnings as errors:
;; 23:49 <@jackdaniel> bollu: I don't know whether this is documented(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));; https://lispcookbook.github.io/cl-cookbook/error_handling.html#handler-case-vs-handler-bind(defun divide (x y) (assert (not (zerop y)) (y) ;; list of values that we can change. "Y can not be zero. Please change it") ;; custom error message. (/ x y))- common lisp libraries read-the-docs
- Code eval play loop: livecoding opengl things
- Consider lispy instead of
parinfer. -
cl-replfor quick command line hackery. - stdlib is large.
- Loading new libraries:
(ql:quickload "str")