LISP CHEAT SHEET A cheat sheet on some Lisp data types that are probably familiar to you as a non-Lisp coder. COMMON NON-BASIC DATA TYPES HASH-TABLE A hash table LIST A singly linked list ARRAY A multidimensional array, possibly resizable VECTOR A one-dimensional array, possibly resizable SIMPLE-VECTOR A one-dimensional array, not resizable STRING A one-dimensional array of characters, not resizable (why this isn't a subtype of simple-vector I don't know) SEQUENCES: Super type of all lists and vectors (including strings) HOW TO SET VALUES: Use SETF on any expression which gets a value. For example, to get a value out of the hash table MY-TABLE, keyed with the key "foo", you say: (gethash "foo" my-table) Likewise, to set the value of keyed with "foo" on MY-TABLE to 3, you say: (setf (gethash "foo" my-table) 3) Let's try again. Let's say you have a list of sublists. To get the first element out of the fourth sublist in a list MY-LIST, you could say: (first (elt my-list 3)) Likewise, to set that value to "Hello", you could say: (setf (first (elt my-list 3)) "Hello") Always use SETF. Do NOT use SETQ, SET, RPLCA, etc. ALL SEQUENCES: Making: make-sequence (rarely used) Nth Element: elt Size: length Joining: concatenate Copying: copy-seq Subsequences: subseq search mismatch Discovery: position (see also: position-if, position-if-not) count (see also: count-if, count-if-not) find (see also: find-if, find-if-not) Type Testing: (type-p MY-SEQUENCE 'sequence) Element Testing: some every notany notevery Bulk Operations: remove (destructive variant: delete) (see also: remove-if, remove-if-not) (see also: delete-if, delete-if-not) remove-duplicates (destructive variant: delete-duplicates) substitute (destructive variant: nsubstitute) (see also: substitute-if, substitute-if-not (see also: nsubstitute-if, nsubstitute-if-not) fill reverse (destructive variant: nreverse) sort (note sort is destructive) (see also: stable-sort) Iterating: map (lists have their own special iterators) (see also: do ) (see also: loop ) LISTS: (remember, lists are sequences) Literals: '(1 2 3 4 5) () ;; no need for quote nil Making: (list 1 2 3 4 5) (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 nil))))) Nth element: nth (but you should use elt instead, except when efficiency is paramount) Getting: first rest last butlast nthcdr (also use sequence functions) Bulk Operations: (use sequence functions) Deep-copying: copy-tree Type Testing: consp null atom (not (consp LIST)) listp (or (consp LIST) (null LIST)) Iterating: dolist mapcar (destructive variant: mapcan) mapc mapl maplist (destructive variant: mapcon) (also use sequence functions) ARRAYS: Literals: #2A((1 2 3) (4 5 6)) ;; a 2x3 unextensible array Making: (make-array '(2 3)) ;; there are many options here Getting: aref Dimensions: array-dimensions Copying: See http://lemonodor.com/archives/000100.html Reshaping: adjust-array Type Testing: arrayp ;; note: also works for all vectors and strings Iterating: For one-dimensional arrays, that is, vectors, use sequence functions For n-dimensional arrays, you can 'cast' them into vectors like this: (let ((vec (make-array (apply #'* 1 (array-dimensions my-array)) :displaced-to my-array))) ... now you can iterate over the vector 'vec' ) VECTORS: (Extensible vectors. Remember, vectors are sequences and also arrays) Literals: None. But simple-vectors have them. Making: (make-array '(10) :adjustable :fill-pointer t) ;; other options Getting: (use sequence functions) Copying: (use sequence functions) Bulk Operations: (use sequence functions) Reshaping: vector-push-extend vector-pop Type Testing: vectorp ;; note: also works for simple-vectors and strings Iterating: (use sequence functions) SIMPLE-VECTORS: (Not extensible. Remember, simple-vectors are sequences, vectors, and arrays) Literals: #(1 2 3 4 5) Making: (vector 1 2 3 4 5) Getting: (use sequence functions) Bulk Operations: (use sequence functions) Copying: (use sequence functions) Type Testing: simple-vector-p Iterating: (use sequence functions) STRINGS: (Not extensible. Remember, strings are sequences, simple-vectors, vectors, and arrays) Literals: "Hello, World!" Making: (make-string 10 :initial-element #\a) Getting: (use sequence functions) Copying: (use-sequence functions) Bulk Operations: string-upcase (destructive variant: nstring-upcase) string-downcase (destructive variant: nstring-downcase) string-capitalize (destructive variant: nstring-capitalize) string-trim string-right-trim string-left-trim Type Testing: stringp Comparison: string= (case insensitive: string-equal) string< (case insensitive: string-lessp) string> (case insensitive: string-greaterp) string<= (case insensitive: string-not-greaterp) string>= (case insensitive: string-not-lessp) string/= (case insensitive: string-not-equal) Iterating: (use sequence functions) HASH TABLES: Literals: None Making: (make-hash-table :test #'equal) ;; I suggest using #'equal always Getting: gethash hash-table-count Deleting: remhash Copying: See first function in http://common-lisp.net/~loliveira/darcs/alexandria/hash-tables.lisp Bulk Operations: clrhash Type Testing: hash-table-p Iterating: maphash