common lisp
Table of Contents
- 1. Package management:
quicklisp
- 2. Development Environment:
sly
- 3. Notes from ANSI Common Lisp
- 3.1. form
- 3.2. evaluation
- 3.3. reading lisp
- 3.4. io
- 3.5. variable
- 3.6. iteration
- 3.7. progn
- 3.8. using function (not at root slot)
- 3.9. manifest typing
- 3.10. exercies of chapter 2
- 3.11. list
- 3.11.1. cons
- 3.11.2. equality
- 3.11.3. setf
- 3.11.4. building list
- 3.11.5. access list
- 3.11.6. maps
- 3.11.7. trees
- 3.11.8. recursion
- 3.11.9. keyword
- 3.11.10. set
- 3.11.11. seq
- 3.11.12. stacks
- 3.11.13. dotted list
- 3.11.14. assoc-list
- 3.11.15. garbage collection with list(or consing)
- 3.11.16. exercises in chapter 3 List
- 3.12. data structures
- 3.13. strucutre of recursive function
- 3.14. toplevel
- 4. ASDF (Another System Definition Facility)
- 5. Reference
- Backlinks
common lisp is a specification lisp, with various of implementation. SBCL is what I refer to most here.
1. Package management: quicklisp
quicklisp is a common lisp package manager, written in common lisp. You need a working common lisp(like SBCL) to run it.
(ql:quickload system-name)
in the interpreter.
(ql:uninstall system-name)
(ql:system-apropos substring)
2. Development Environment: sly
sly is a emacs mode, derived from SLIME
. They are, at respective times, de facto best IDE for common lisp.
3. Notes from ANSI Common Lisp
3.1. form
- all lisp expressions are either
- atom
- like 1. or
- list
- consisting zero or more expressions enclosed in parentheses
3.2. evaluation
lisp is a token tree, with the leafs atoms(which evaluate to themselves). The evaluation starts from leafs up, from left to right.
3.3. reading lisp
- use indentation to replace most parens [especially when writing code on paper
3.4. io
- format dest foramt-string &rest obj
- dest
- where format prints. t means toplevel
- format-string
- ~% means newline, ~A means an obj.
- wait for input, parse what ever is give, return the lisp object of it
3.5. variable
3.5.1. local variable
(let)
3.5.2. global variable
defparameter. blog
3.5.3. global constant
defconstant
3.5.4. boundp
check if a symbol is bounded
3.5.5. assignment-setf
setf
- would bound if the symbol is unbounded
- work on both local and global variables nn
(setf a 'x b 'y c 'z) (setf (car '(x y z)) 'n)
3.6. iteration
3.6.1. do
(do ((i 0 (+ i 1)) ;; var initial update (j 1 (+ j 1))) ((> i 10) 'done) ;; end-p return (format t "i: ~A, j:~A, ~%" i j) )
3.6.2. dolist
(dolist (x '(1 2 3)) (format t "x: ~A~%" x))
3.7. progn
evaluate expressions
3.8. using function (not at root slot)
- #’+ qoute function
(funcall #'+ 1 2 3) (apply #'+ '(1 2 3))
- apply need the last arg to be a list. funcall don’t.
(lambda (x) (+ 100 x)) #'(lambda (x) (+ 100 x))
3.9. manifest typing
variable don’t have type. Values have type
(typep 27 'integer)
3.10. exercies of chapter 2
(defun that-many-dots-it (x) (do ((num x (- num 1))) ((= num 0)) (format t ".") ) ) (defun that-many-dots-re (x) (if (= x 1) (format t ".") (progn (format t ".") (that-many-dots-re (- x 1)) ) ) ) ;; (that-many-dots-it 3) (that-many-dots-re 3)
(defun summit (lst) (remove nil lst) (apply #'+ lst) )
3.11. list
3.11.1. cons
cons : a data structure that is a pair of pointers.
- list from cons
- first pointer to value, second pointer to next cons
- (no term)
- the box notation of cons
- nexted list and flat list
3.11.2. equality
(eql (cons 'a nil) (cons 'a nil))
eql return t when args are the same object
(equal (cons 'a nil) (cons 'a nil))
equal return t when args would print the same
3.11.3. setf
set field
(setf x '(1 2)) (setf (car x) 4) ;; (car x) is a pointer x
3.11.4. building list
- copy-list x return a list that equal x but not eql x (point to same things in cars, but different set of pointers on differnet addresses)
append arg1 arg2... argn
copy arg1…argn-1 and concatenate them to argn.
3.11.5. access list
(nth 0 '(a b c)) (nthcdr 2 '(a b c)) (zerop 3) (last '(a b c)) ;; car it to get the atom (first '(0 1 2 3 4 5 6 7 8 9)) (tenth '(0 1 2 3 4 5 6 7 8 9)) ;; first - tenth are defined. (cadddr '(0 1 2 3 4 5 6 7 8 9)) ;; can use, but not necessary, and hard to read.
3.11.6. maps
- mapcar apply function to elements(cars)
- maplist apply function to cdrs
;; (mapcar #'(lambda (x) x) '(1 2 3)) (maplist #'(lambda (x) x) '(1 2 3))
3.11.7. trees
lists can be view as binary trees (cons can have up to 2 pointers) with no interior value. It’s not very useful as data strucutre, but useful when you have nested lists and you need to go into and over them
(copy-tree '(1 (2 3) 4)) ;; with copy-list, they will have the (setf x (copy-list '(1 (2 3) 4))) (setf y (copy-list x)) ;; (setf y (copy-list '(1 (2 3) 4))) (eql (nth 0 x) (nth 0 y)) (substitue 3 2 '(1 (2 3) 4)) (subst 3 2 '(1 (2 3) 4)) ;; substitute in a tree
- doubly recursive
- function operate on tree often recurse down both car and cdr
3.11.8. recursion
A recursion would do its job if it covers all the cases.
don’t forget the base case. They are usually with (null lst)
like stuff. (for the last element of the list)
3.11.9. keyword
(member 'a '((a b) (a c) (b c)) :key #'car :test #'equal) ;; for member, the predicate would be: ;; (equal 'a (car '(a b))) ;; key only apply to the LST
- keyword arguments are optional, come at end, and order don’t matter.
3.11.10. set
(member-if #'oddp '(2 3 4)) ;; with an arbitary predicate. (adjoin 'b '(a b c)) ;; join only when not a member (union '(a b c) '(b c d)) (intersection '(a b c) '(b c d)) (set-difference '(a b c) '(b c d)) ;;complement, what the first have and the second don't
3.11.11. seq
list could be conceived as sequence
(length '(1 2 3)) (subseq '(a b c d) 1 2) (reverse '(a b c d)) (sort (copy-list '( 1 2 3 4 )) #'> ) ;; sort is destructive, so pass a copy to avoid original list being modified (every #'oddp '(1 2 3)) (some #'oddp '(1 2 3)) (every #'< '(1 2 3) '(2 3 4))
3.11.12. stacks
list could be seen as stacks
(setf x '(2 3 4)) (push 1 x) (pop x) (pushnew 2 x) ;; use adjoin instead of cons, so only new element be pushed
3.11.13. dotted list
literal is '(A . B)
- proper list
- that created with
list
and qoute. cdr is either another proper list or nil - dotted list
- or, cons cell. A 2 field data structure, car and cdr can point to anything.
3.11.14. assoc-list
(setf x '((+ . "add") (- . "sub") (1 2 3))) (assoc '+ x) (assoc 1 x) ;;assoc take :test and :key too
3.11.15. garbage collection with list(or consing)
it could be expensive, while the alternative may be more expensive. An educated heuristic is to:
- write the program in pure functional style with lots of lists.
- find critical portions and use destructive functions/special data structures on that
3.11.16. exercises in chapter 3 List
(defun occurrences (LST) "return an alist '((a . 4) (b . 3)) with '((ELT . OCCURANCE)), sorted ascendingly" (let ((result '())) (dolist (ELT LST) (if (member ELT result :key #'car) (setf (cdr (assoc ELT result)) (+ 1 (cdr (assoc ELT result)))) (push (cons ELT 1) result) ) ) (sort result #'> :key #'cdr) ) ) (occurrences '(b b a d c a b d a a )) (defun range (max &key (min 0) (step 1)) (loop for n from min below max by step collect n)) (defun pos+ (LST) "each element + its position" (mapcar #'+ LST (range (length LST))) ) (pos+ '(0 0 0 0)) (defun show-dots (LST) "print dot notation of LST" (show-dots- LST 0) ) (defun show-dots- (LST count) (if (null LST) (format t (concatenate 'string "NIL" (string-of count ")"))) (progn (format t "(~A . " (car LST)) (show-dots- (cdr LST) (+ count 1)) )) ) (defun string-of (N STR) (apply #'concatenate 'string (make-list N :initial-element STR)) ) (show-dots '(a b c)) (defun new-paths-no-dup (PATH NODE NET) "return a list of path dispatched at NODE" (if (null PATH) nil (mapcar #'(lambda (next) (if (member next PATH) nil (cons next PATH) )) (cdr (assoc NODE NET)) )) ) (defun longest-finite-path- (PATHS PATHS-DONE NET) (if (every #'null PATHS) (sort PATHS-DONE #'> :key #'length) (longest-finite-path- (append (cdr PATHS) (new-paths-no-dup (car PATHS) (car (car PATHS)) NET)) ;; PATHS (if (every #'(lambda (next) (member next (car PATHS))) (cdr (assoc (car (car PATHS)) NET))) (cons (car PATHS) PATHS-DONE) PATHS-DONE ) NET )) ) (defun longest-finite-path (NET) (longest-finite-path- (list (list (car (car NET)))) nil NET) ) (longest-finite-path '((a b c) (b c) (c d)))
3.12. data structures
3.12.1. array
(setf arr (make-array '(2 3) :initial-element nil)) (setf arr1d (make-array 4 :initial-element nil)) ;; also a vector (setf vec (vector "a" 'b 3)) (svref vec 0) ;; a faster aref for vec simple vector (setf (aref arr 0 0) 'b) ;; #2a((b nil nil)) the way to print if *print-array* is t ;; #na n is dimension ;; #("a" B 3) is a vector (aref arr 0 0)
- sv - simple vector
- not adjustable, not displaced, don’t have fill-pointer
3.13. strucutre of recursive function
(defun recursive (args col) (recursive- arg1 arg2 arg3 col) ) (defun recursive- (arg1 arg2 arg3 col) (if (null col) base-case-1 (if predicate (recursive- arg4 arg5 arg6 col-modified) (recursive- arg7 arg8 arg9 col-modified-2) ) ) )
- typically, 2 functions, one is entry and the other is called in entry and have a more formalized recursive structure
3.14. toplevel
- * * and ** refer to the last 3 values returned in the toplevel
4. ASDF (Another System Definition Facility)
ASDF is used to build and load softwares(libraries). It’s successor of defsystem
.