Search notes:

Lisp

The name Lisp, which originally was spelled with upper case letters (LISP), derives from LISt Processor.
The source code of a Lisp program consists of lists.
In Lisp, everything is either
A list contains atoms or other lists. These elements are put within parenthesis and separated with commas.
Atoms are literals like 42, "Hello World" or symbols (names of variables or functions).
A symbol is a string of (latin?) letters and digits.
Unless instructed otherwise, a list triggers a function call, the first argument being the name of the function.

S-expressions and lists

S-expression stands for symbolic expression and is sometimes abbreviated as sexpr.
An S-expression is either
A list is similarly defined as
(a b c) is just a short hand notation for (a . (b . (z . NIL)))
A list may contain code or data.
NIL is the special end-of-list object, sometimes also expressed as (). (In Scheme, NIL seems to be represented as nil).
See also M-expressions which stands for meta-expression.

NIL and () is the same object

* (eq '() 'nil)
T

cons (data structure)

A cons is a data structure that contains two values.
The cons' first value is its car, the second value its cdr).

cons (function)

(cons A B) is the function to create a cons (denoted with the S-expression (x . y)?).
* (cons 1 2)
(1 . 2)

* (cons 1 '(2 3))
(1 2 3)

* (cons 'one '(two three)) ; Note the quoted one
(ONE TWO THREE)

* (cons '(one two) 'three)
((ONE TWO) . THREE)
cons is one of McCarthy's five elementary functions.

cond

cond takes n lists with two elements:
* (cond
    (nil  "first is true"  )
    (t    "seoncd is true" )
    (t    "third is true"  )
)
"second is true"
Evaluating the values in the n lists:
* (let (  (x 10) (y 15) )
  (cond
   ( (> x y)  "x is greater than y"  )
   ( (< x y)  "x is less than y"     )
   ( (= x y)  "x is equal to y"      )
  )
)

* (let (  (x 10) (y 15) )
  (cond
   ( (> x y)  (write-line "x is greater than y") )
   ( (< x y)  (write-line "x is less than y"   ) )
   ( (= x y)  (write-line "x is equal to y"    ) )
  )
)
The L-shaped evaluation in cond
* (cond
    ( nil                             5                                     )
    ( nil                            (this list is not evaluated          ) )
    ( (> 5 10)                       (neither is this list evaluated      ) )
    ( (< 5 10)                       (write-line "this list is evaluated" ) )
    ( (this list is not evaluated)   (this list is not evaluated          ) )
)
cond is one of the Paul Graham's seven primitives.

car / cdr (functions)

car evaluates to the first element in a list.
* (car '(a b c))
A

* (car '( (a b c) d e f))
(A B C)

* (car '())
NIL
* (car (cons (cons 1 2) (cons 3 4)))
(1 . 2)
cdr evaluates to the second element in a list (in the liturature typically referred to as «the rest»)
* (cdr (cons (cons 1 2) (cons (cons 3 4) 5)))
((3 . 4) . 5)
* (cdr '(A B C D))
(B C D)
car stands for Contents of the Address part of the Register number, cdr for Contents of the Decrement part of the Register numer.
The «register» in these terms refered to words(?) (x bytes?) in memory, not to registers on the CPU as understood today.
The full contents of a register number (i.e. car and cdr) can be used to represent a cons cell.
car and cdr belong to McCarthy's five elementary functions.
List:
* (car    '(one two three four five))
ONE

* (cadr   '(one two three four five))
TWO

* (caddr   '(one two three four five))
THREE

* (cadddr  '(one two three four five))
FOUR
List of lists:
* (caar    '((one two three) (1 2 3)))
ONE

* (cadar   '((one two three) (1 2 3)))
TWO

* (caddar  '((one two three) (1 2 3)))
THREE

* (cdar    '((one two three) (1 2 3)))
(TWO THREE)

* (cadr    '((one two three) (1 2 3)))
(1 2 3)

* (caadr   '((one two three) (1 2 3)))
1

* (cadadr  '((one two three) (1 2 3)))
2

(cadr X)

(cadr X) is an abbreviation («syntactic sugar) for (car (cdr X)):
* (car (cdr (list 1 2 3 4)))
2
Same same, but shorter:
* (cadr (list 1 2 3 4))
2

list (data structure)

A cons is also a list if its cdr is

Examples of lists

The cdr is nil:
* (cons 3 nil)
(3)
The cdr of the outer cons is a list (as per previous example):
* (cons 2 (cons 3 nil))
(2 3)
Because the definition of a list is recursive, this can be extended ad infinitum:
* (cons 1 (cons 2 (cons 3 nil)))
(1 2 3)

(list …)

list is the function to create lists
* (list 1 2 3 4 5)
(1 2 3 4 5)
The same list can also be created with a sequence of (cons…) functions. Note the nil in the last (cons 5 nil):
* (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 nil)))))
(1 2 3 4 5)

Representing cons

A cons is represented with with a pair of parentheses that contains its values, that are themselves separated by a dot.
A simple cons:
* (cons 1 2)
(1 . 2)
A cons whose car is a cons:
* (cons (cons 1 2) 3)
((1 . 2) . 3)
The dot and the parenthesis around the cdr are omitted when its cdr is
There is no such rule that is dependent on cons' car.
There are nine combination how cons-cell can be constructed:
* (cons 'a 'b)
(A . B)

* (cons 'X (cons 'Y 'Z))
(X Y . Z)

* (cons 'Q nil)
(Q)

* (cons (cons 'U 'v) 'W)
((U . V) . W)

* (cons (cons 'ONE 'TWO) (cons 'THREE 'FOUR))
((ONE . TWO) THREE . FOUR)

* (cons (cons 'hello 'world) nil)
((HELLO . WORLD))

* (cons nil 1)
(NIL . 1)

* (cons nil (cons 1 2))
(NIL 1 . 2)

> (cons nil nil)
(NIL)

Quoting lists

In order to prevent the evaluation of a list, the list must be quoted. This is possible with either a single apostrophe, a backtick or the pseudo function quote:
* (+ 1 2 3)
6

* `(+ 1 2 3)
(+ 1 2 3)

* '(+ 1 2 3)
(+ 1 2 3)

* (quote (+ 1 2 3))
(+ 1 2 3)

quote, function

'frm is identical to (quote frm)
#'fn is identical to (function fn)

defun

defun is a (macro(?) / special operator()) to create a function.
The name of the function can also be used for a variable. symbol-value and symbol-function allow to query the respective value:
* (defvar pq 21)
PQ

* (defun pq (x) (* 2 x))
PQ

* (pq pq)
42

* (symbol-value    'pq)
21

* (symbol-function 'pq)
#<FUNCTION PQ>

defvar

* (defvar num 42)
NUM

* (setq num (- num 12))
30

* (setf num (* num 3 ))
90

* (print num)
90
90

lambda

The common lisp manual says that the macro lambda is a dubious shortcut for (function (lambda ...)) or #'(lambda ...) - but offers no explanation as to why that is:
* (macroexpand '(lambda (x) (x)) )
#'(LAMBDA (X) (X))
T
A labmda expression can be thought of as a name of a function which appears as the first element in a list, giving raise to the following anonymous use of a lambda:
* (
    (lambda (x)  (* 3 x))
    14
  )
42
Combining defun with lambda:
* (defun twice (n)
  (
    (lambda (x) (* 2 x)) n
  )
)
TWICE

* (twice 21)
42
Multiple parameters
* ( (lambda (x y z)  (* z y x)) 7 3 2)
42
With SBCL, the type of a lambda expression is COMPILED-FUNCTION. In CLISP, it is just FUNCTION.
* (type-of (lambda (x) (* 3 x)) )
COMPILED-FUNCTION
Because a function that is defined with a lambda-expression has no name, this function cannot refer to itself.
Hence, lambda cannot be used to create recursive functions.

Applying functions to elements in a list

Functions that apply a function to the elements in a list include
The common lisp manual points out that macros cannot be used as functional arguments to such functions as apply, funcall or map.

mapcar

Apply a function to each element of a list. Note that the name of the function in (mapcar 'twice …) is quoted. Without quoting it, the interpreter would throw an error.
* (defun twice (x) (* x 2))
* (mapcar 'twice '(2 5 3))
(4 10 6)

map

The first argument to map is the type of the returned value.
* (map  'list    (lambda (x) (+ 2 x)) '(10 7 3 18 9) )
(12 9 5 20 11)

* (map  'vector  (lambda (x) (+ 2 x)) '(10 7 3 18 9) )
#(12 9 5 20 11)

funcall

* (defun f(fn) (funcall fn 1 2 3 4))
F

* (f '+)
10

* (f '*)
24

apply

apply generally takes two arguments …
* (apply #'+ '(1 2 3 4))
10
… but can be called with more arguments, too:
* (apply #'+ 1 2 '(3 4))
10
* (apply (symbol-function '+) '(1 2 3 4))
10
* (apply #'(lambda (a b c d) (+ a b c d)) '(1 2 3 4))
10

sort

Sort numbers in ascending order:
* (sort '(8 5 3 4 6) #'<)
(3 4 5 6 8)
Sort strings alphabetically
* (sort
     '("eight" "nine" "ten" "eleven" "twelve")
    #'string<)
Sort strings according to their length
* (sort
     '("eight" "nine" "ten" "eleven" "twelve")
    #'(lambda (str1 str2) (< (length str1) (length str2))))
("ten" "nine" "eight" "eleven" "twelve")

remove-if

Remove even numbers:
* (remove-if #'evenp '(7 2 6 4 3 8 5))
(7 3 5)

Calling a function (lambda expression0 returned from a function

(defun create-func (x)
   (lambda (y) (write-line (concatenate 'string x " " y)))
;#'(lambda (y) (write-line (concatenate 'string x " " y)))   ; same same but different?
)

(defvar f1)
(defvar f2)

  (setf                   f1  (create-func "f1"))
  (setf (symbol-function 'f2) (create-func "f2"))
; (setf                 #'f3) (create-func "f3")) ; --> Error

  (funcall          f1  "one"  )
  (                 f2  "two"  )
; (               #'f1  "three") ; --> error
; ((symbol-function f1) "four" ) ; --> error

Sequential evaluation

* (progn
   (defvar X 6)
   (defvar Y 7)
   (* X Y)
)
42

; Value of defvar is retained ...
* X
6
Scheme (petite):
(begin
   (define X 6)
   (define Y 7)
   (* X Y)
)

setq

setq (a special operator) is the simple variable assignment statement and can be used to assign values to both lexical and special variables.
It returns the last assigned value.
(defvar a)
(defvar b)
(defvar c)


(setq        ; Assign
   a    6    ; 6 to a
   b    7    ; 7 to b
   c (* a b) ; 6*7 to c
)

(print c) ; 13

let, let*, flet

* (let (
     (x "hello")
     (y "world")
  )
  (concatenate 'string x " " y)
)
"hello world"
In a let expression, the value of a newly defined variable cannot depend on the value of another newly defined variable, thus the following expression throws an error:
* (let (
     (x  21    )
     (y (* x 3))
    )
    (print (- y x))
  )
However, with let*, assigning values in sequence is possible:
* (let* (
     (x  21    )
     (y (* x 3))
    )
    (print (- y x))
  )
42
42
Share a (hidden) variable between two functions (See Paul Graham - On Lisp - 2.6. Closures):
* (let ((counter 0))
   (defun new-id   () (incf counter  ))
   (defun reset-id () (setq counter 0))
)
RESET-ID

* (new-id)
1

* (new-id)
2

* (reset-id)
0

* (new-id)
1
flet names local functions:
* (flet (
    ( f (x)
       (print (concatenate 'string "outer f: " x))
       (flet (
           ( f (x)
              (print (concatenate 'string "inner f: " x))
           )
          )
          (f "two")
      )
    )
   )
    (f "one")
  )
"outer f: one"
"inner f: two"
"inner f: two"
labels is similar to flet with the difference that a function defined in labels can be used in the function being defined:
* (labels (
    ( fib (n)
       (
         if (<= n 2)
           1
           (+ (fib (- n 1)) (fib (- n 2)))
       )
    )
   )
    (fib 7)
  )
Example of using labels in a function (Graham - On List, p. 3):
* (defun reverse-list (lst)
   (labels (
      ( reverse-local (lst accum)
        (if (null lst)
           accum
          (reverse-local (cdr lst) (cons (car lst) accum ))
        )
      )
   )
     (reverse-local lst nil)
   )
)
REVERSE-LIST

* (reverse-list '(5 4 3 2 1))
(1 2 3 4 5)
Compare flet and labels with macrolet.

define vs let vs setq …

let creates a new lexical scope
setq assigns a value to an existing variable.
Then, there is also let* and letrec.
What is define doing, anyway?

TODO

McCarthy's five elementary functions

atom Is something atomic?
eq Check if two atomic things are equal?
car The left part of an S-expression
cdr The right part of an S-expression
cons Constructs an S-expression from two atoms
In The Roots of Lisp, Paul Graham adds the following two «primitives»: quote and cond (which he names the Seven Primitive Operators).
An environment that implements only those five (seven?) functions is a programming language.
Because of this simplicity, Steven Russel was able to create (the abstract machine called eval) in a few days on an IBM 709 computer.
Compare this with say C or what not - but also with the 25 special forms of Lisp.
These five/seven functions (primitives) allow to create 12 additional functions (but how, defun is not part of these 5/7), it is possible to create the universal function eval which is able to evaluate Lisp in Lisp. These 12 functions are: null, and, not, (caar, cadr, caddr, cadar, caddar), append, list, pair and assoc`
This(?) unversal language was already presented by McCarthy himself in chapter 1.6 of the LISP 1.5 Programmer's Manual.
Alan Kay referred to this universal language as Maxwell’s Equations of Software.

define vs defun

define is a function that is available in Scheme but not in Common Lisp.
defun is a function that is available in Common Lisp, but not in scheme.
Scheme:
> (define (twice x) (* x 2))
> (twice 2)
4
Common Lisp (sbcl)
* (defun twice (x) (* x 2))
* (twice 2)

Variables

Common Lisp has two types of variables:
  • Ordinary variables, used to name data objects
  • Function names, used to name defined functions, macros and special operators
Common Lisp also has two kinds of variables:
  • Lexical (or static) variables
  • Special (or dynamic) variables (which are preferrably declared with defvar). Generally, the names of special variables start and end with *. See also (proclaim '(special …))
A Function name is either
  • a symbol, or
  • a list with two elements whose first element is the symbol setf and whose second element is a symbol.

Accessing und updating variables

The dynamic value of a variable can be accessed and updated like so:
Accessing Updating Updating using setf
sm (setq sm new-value) (setf sm new-value)
(car ls) (rplaca ls new-value) (setf (car ls) new-value)
(symbol-value sm) (set sm new-value) (setf (symbol-value sm) new-value)
Thus, having setf makes setq, rplaca and set redundant.

macro-function

macro-function determines if a given symbol is the name of a macro.
* (if (macro-function 'if    )     "if is a macro"     "if is not a macro")
"if is not a macro"

* (if (macro-function 'lambda) "lambda is a macro" "lambda is not a macro")
"lambda is a macro"

Special forms

A special form: a list, other than a macro form, which is a form with special syntax or special evaluation rules or both, possibly manipulating the evaluation environment or control flow or both. The first element of a special form is a special operator.
Special forms are special because each of them has a special semantics.
Some (all?) predecessors of Common Lisps (such as MacList) had even more special forms. This number was apparently reduced to 25 in Common Lisp because of Kent Pitman.
Scheme has reduced the number of special forms even more.
See also: the 25 special forms

Special operators

block Like progn but with the possibility to bail out with return or return-from. See also do and prog.
catch See also throw
declare Why is it in this list, it is missing here.
eval-when
flet Define locally named functions. Compare with let
function
go
if
labels
let Execute a series of forms with specified variables bound to the specified values. Compare with progn and flet.
let* Like let but variables are bound in sequence.
load-time-value
locally
macrolet
multiple-value-call
multiple-value-prog1
progn Evaluate forms in a sequence (think { … } in C. Compare with the prog1 macro, and the let and block special operators.
progv Usefule when writing interpreters for languages embedded in Lisp.
quote
return-from See also the macro return.
setq The simple variable assignment statement.
symbol-macrolet
tagbody
the
throw See also catch
unwind-protect
What about:
  • and, or
  • cond
  • defconstant
  • defparameter (Creates a global variable which, when changed, is considered changing the program, i. e. the value of the variable is a parameter of the program. Compare with defvar and defconstant)
  • defun (whose purpose is to define a named function)
  • defvar (The recommended way to declare the use of a special variable in a program. Compare with defparameter and defconstant)
  • do
  • eval-when
  • go
  • multiple-value-bind
  • multiple-value-call
  • multiple-value-list
  • multiple-value-prog1
  • multiple-value-setq
  • prog* (which is to prog as let* is to let)
  • sample-special-form
  • tagbody
  • with-open-file
See also special-operator-p which determines if a symbol globally names a special operator

Read-eval-print loop (REPL

The REPL is typically used to interact with the Lisp interpreter:
  • Read a form from an input-source (file, terminal …)
  • Evaluate the form
  • Print the value to an output sink (terminal, screen, file …)

macroexpand / macroexpand-1

In SBCL:
* (macroexpand '(setf (car x) y))
(SB-KERNEL:%RPLACA X Y)
T
* (defmacro cond_ (&rest clauses)
    (when clauses
     `(if ,(caar clauses)                   ; Note to self: backtick
         (progn ,@(cdar clauses))
         (cond_ ,@(cdr  clauses)))))

* (macroexpand '(cond_ (a b) (c d) (e e) (f g)))
(IF A
    (PROGN B)
    (COND_ (C D) (E E) (F G)))
T

* (defun macroexpand-tree (tree)
    (setq tree (macroexpand tree))
    (if (atom tree)
       tree
       (mapcar #'macroexpand-tree tree)))
MACROEXPAND-TREE

* (macroexpand-tree '(cond_ (a b) (c d) (e e) (f g)))
(IF A
    (PROGN B)
    (IF C
        (PROGN D)
        (IF E
            (PROGN E)
            (IF F
                (PROGN G)
                NIL))))

setf expanders

The following example was expired (mostly copied even) from this Stackoverflow question.
* (defvar arr (make-array 5 :initial-contents '(zero one two XYZ four)))
ARR
*
(defun arr-elem (n) (aref arr n))
ARR-ELEM
*
(arr-elem 3)
XYZ
*
(setf (arr-elem 3) 'three)
…
("undefined function" THREE 3)
In order to be able to use setf to set the value of an element in arr, we use a setf expander.
Note: the first parameter is used for the new value (new-val).
*
(defun (setf farr-elem) (new-val n)
    (setf (aref arr n) new-val)
)
(SETF FARR-ELEM)
*
(setf (farr-elem 3) 'three)
THREE
*
(arr-elem 3)
THREE
By convention, any function named (setf fn) should return its first argument as its only value, in order to preserve the specification that setf returns its new value.

quote

* (quote (this list is not evaluated))
(THIS LIST IS NOT EVALUATED)
* (quote (A . (B . (C . ()))))
(A B C)
quote is one of the Paul Graham's seven primitives.

function

* (defun twice (x) (* 2 x) )
* (function twice)
#<FUNCTION TWICE>

* #'TWICE
#<FUNCTION TWICE>
* (function (lambda (x) (* 3 x)))
#<FUNCTION (LAMBDA (X)) {52A4ADDB}>

function-lambda-expression (Recover the source of a defined function)

* (defun fn (a b) (+ a b))
* (function-lambda-expression #'fn)
(LAMBDA (A B) (BLOCK FN (+ A B)))
T
FN

* (function-lambda-expression #'function-lambda-expression)
NIL
T
FUNCTION-LAMBDA-EXPRESSION

* (function-lambda-expression #'does-not-exist)
… error …

Equality predicates (eq etc.)

eq
eql
equal
equalp Like equal but ignores type differences. The most general function of all.
eq is one of McCarthy's five elementary functions.
However, his version of eq could only compare atoms while common lisp allows to compare any two objects.
* (equalp 5 5.0)
T

* (equal 5 5.0)
NIL
* (let ((A "xyz"))(eq A A))
T

* (let ((A "xyz")(B "xyz")) (eq    A B))
NIL

* (let ((A "xyz")(B "xyz")) (eql   A B))
NIL

* (let ((A "xyz")(B "xyz")) (equal A B))
T

* (let ((A "xyz")(B "xyz")) (equalp A B))
T
* (eq 255 #xff)
T
* (eq    '((A . B) . (C . D))
         '((A . B)    C . D )
  )
NIL

* (equal '((A . B) . (C . D))
         '((A . B)    C . D )
  )
T
* (eq  'g 'h)
NIL

* (eq  'h 'h)
T
* (defvar fn #'print)
FN

* (eq (symbol-value 'fn) (symbol-function 'print))
T

typep, subtypep, type-of

(type-of obj) never returns nil because each object has a type.
(typep obj (type-of obj) always returns t.
* (type-of ())
NULL

* (type-of '())
NULL

* (type-of 'NIL)
NULL

* (type-of NIL)
NULL

* (type-of T)
BOOLEAN

* (type-of 'T)
BOOLEAN

* (type-of 'XYZ)
SYMBOL

* (type-of '(1 2 3))
CONS

* (type-of 42)
(INTEGER 0 4611686018427387903)

* (type-of 42.99)
SINGLE-FLOAT

* (type-of 42.99L0)
DOUBLE-FLOAT

* (type-of "42.99")
(SIMPLE-ARRAY CHARACTER (5))

* (type-of #'type-of)
COMPILED-FUNCTION

* (type-of (lambda (x) (* 3 x)) )
COMPILED-FUNCTION

* (type-of (type-of NIL))
SYMBOL

* (type-of #\c)
STANDARD-CHAR

* (type-of 10/3)
RATIO

* (type-of (make-array 5))
(SIMPLE-VECTOR 5)
* (type-of  *standard-input*)
SYNONYM-STREAM

* (type-of '*standard-input*)
SYMBOL

* (type-of #(a b c d))
(SIMPLE-VECTOR 4)

* (type-of #P"$ this path doesn't exist!")
PATHNAME

* (let (( x 42 )) (type-of x))
(INTEGER 0 4611686018427387903)
* (typep '(a b c) 'cons)
T

* (typep 42 'cons)
NIL
42 is both an integer and and atom.
* (typep 42 'integer)
T

* (typep 42 'atom)
T
Similarly, "text" is both a string and and atom:
* (typep "text" 'string)
T

* (typep "text" 'atom)
T
Double float vs single float:
* (typep 42.99L0 'double-float)
T

* (typep 42.99L0 'single-float)
NIL
* (type-of (subtypep 'long-float 'float))
BOOLEAN
* (defvar NUM)
NUM

(setq NUM 42)
42

* (type-of NUM)
(INTEGER 0 4611686018427387903)

* (type-of 'NUM)
SYMBOL
* (subtypep 'float 'long-float)
NIL
T

* (subtypep 'long-float 'float)
T
T
See also
  • defstruct (which creates new types)
  • coerce
  • satisfies

atom, consp

(atom obj) ≡ (typep obj 'atom) ≡ (not (typep obj 'cons))
(consp obJ) ≡ (typep obj 'cons) ≡ (not (typep obj 'atom))
* (atom 42)
T

* (atom '(a b c))
NIL

* (atom '((( ))) )
NIL

* (atom '(((X))) )
NIL
((ONE TWO THREE))
* (consp 42)
NIL

* (consp '(a b c))
T
() is nil, so:
* (atom '())
T
* (defvar lst '(a b c))
LST
* (atom  lst)
NIL
* (atom 'lst)
T
* (atom 'undefined-symbol)
T
atom is one of McCarthy's five elementary functions.
* (vectorp #(1 2 3))
T

* (vectorp '(1 2 3))
NIL
(functionp x) ≡ (typep x ’function)
* (functionp #'list)
T

* (functionp #'(lambda (x) (print x)))
T

Printing functions

prin1 Representation of an object. prin1 is intended to be consumed by read, compare with princ.
print Like prin1 except that the printed representation is preceeded by a newline (see terpri) and followed by a space.
pprint Like print except that the trailing space is omitted and the object is printed with the *print-pretty* flag set to nil. Returns no value.
princ Like prin1 except that no escape characters are printed. The output of princ is intended to be consumed by humans, compare with prin1. princ prints a character exactly like write-char
write-to-string
prin1-to-string
princ-to-string
write-char Writes a character (and returns it)
write-string
write-line Compare with read-line
write-sequence
terpri Writes a newline to the output stream. Identical in effect to (write-char #\Newline output-stream). Compare with fresh-line
fresh-line LIke terpri, but only prints a newline if the stream is not at the start of a line. Returns T or F accordingly.
finish-output
force-output
clear-output
write-byte

write-char

* (write-char #\c)
c
#\c

write

* (write "foo")
"foo"
"foo"

* (write 'foo)
FOO
FOO

* (write 2)
2
2

* (write #'write)
#<FUNCTION WRITE>
#<FUNCTION WRITE>

Number sign

#o77 Octal value (of an integer?)
#xff Hexadecimal value
#b0011101011 Binary value
#\C The character C
#(a b c) Vector
#'cons #'fn is to (function fn) as 'xyz is to (quote xyz)

format

Many format operations are directly or indirectly defined in terms of prin1 or princ which are affected by the printer control variables.
~A Ascii
~S S-expression
~D Decimal
~B Binary
~O Octal
~X Hexadecimal
~nR With given radix n. ~@R and ~:@R produce roman numerals
~P Plural
~C Character
~F Fixed floating point
~E Exponential floating point
~G General floating point
~$ Dollars floating point
~% #\Newline. ~n% prints n newlines. See also terpri
~&
~| Page seperator
~~ A tilde
~T Tabulate
~* Ignore an argument
~? Indirection
~_ Conditional new line
~W Write
~I Indent
~(str~) Case conversion
~ can be followed immediately with a «real» newline.
There is also ~[str0 ~;str1 ~;...~;strn~ for conditional expressions (and of course even more).
Common Lisp ed 2, p. 909: All of the existing printing functions (write, prin1, print, princ, pprint, write-to-string, prin1-to-string, princ-to-string, the ~S and ~A format operations, and the ~B, ~D, ~E, ~F, ~G, ~$, ~O, ~R, and ~X format operations when they encounter a non-numeric value) are required to be changed to go through the print-object generic function

defstruct

* (defstruct xyz  num txt)
XYZ
Behind the scenes, the macro defstruct created the function make-xyz:
* (defvar obj)
OBJ

* (setf obj (make-xyz :num 42 :txt "hello world"))
#S(XYZ :NUM 42 :TXT "hello world")
The macro also created the «accessor» functions xyz-num and xyz-txt:
* (xyz-num obj)
42

* (xyz-txt obj)
"hello world"
The macro also created the «type» xyz:
* (type-of obj)
XYZ

* (typep obj 'xyz)
T

* (xyz-p obj)
T
… And also a «copier function»:
* (defvar copy-of-obj)
COPY-OF-OBJ

* (setf copy-of-obj (copy-xyz obj))
#S(XYZ :NUM 42 :TXT "hello world")
Modify struct-objects with setf:
* (setf (xyz-num copy-of-obj) 99)
99

* copy-of-obj
#S(XYZ :NUM 99 :TXT "hello world")

* obj
#S(XYZ :NUM 42 :TXT "hello world")
See also defclass.

loop

* (loop for i from 1 to 5 collect i)
(1 2 3 4 5)

concatenate

* (concatenate 'string "hello"  " "  "world")
"hello world"

make-array

* (make-array 5)
#(0 0 0 0 0)

* (make-array '(2 3))
#2A((0 0 0) (0 0 0))

* (make-array 5 :initial-contents '(3 2 5 4 1))
#(3 2 5 4 1)

:element-type

* (make-array 5 :element-type 'single-float)
#(0.0 0.0 0.0 0.0 0.0)
See also subtypep.

See also

aref

aref

* (let (( a (make-array 6 :initial-contents '(zero one two three four five)) ))
    (aref a 2)
  )
TWO

length

* (length "abcd")
4

&optional

In a parameter list (of a function?), all arguments on the right side of &optional are optional
* (defun ex-1 (param-1 &optional (param-2 "default value"))
    (format t "~a, ~a!~%" param-1 param-2))
EX-1

* (ex-1 "hello")
hello, default value!
NIL

* (ex-1 "hello" "world")
hello, world!
NIL
* (defun ex-2 (param-1 &optional param-2)
   (if param-2
     (format t "~a, ~a!~%" param-1 param-2)
     (format t "~a!~%"     param-1        )
   ))
EX-2

* (ex-2 "hello")
hello!
NIL

* (ex-2 "hello" "world")
hello, world!
NIL
(
See also &rest and &key.

read

read is the so-called «Lisp reader»: it reads characters from an input stream and parses them as representations of Lisp objects.
The behavior of read is controled by readtables.
read &optional input-stream eof-error-p eof-value recursive-p
read reads in the printed representation of a Lisp object from input-stream, builds a corresponding Lisp object, and returns the object.
read seems to be associated with the opening paranethesis (which seems to be a macro)

do

* (do ( (i 0 (1+ i))      ) ; start with i = 0, increment i by one
      ( (>= i 5 )         ) ; end when i is equal or greater than 5
;     ( format t "~d~%" i ) ; print i
      ( print i           ) ; print i
)
0
1
2
3
4
NIL
Compare with do*.

/

* (/ 9 3)
3

* (/ 10 3)
10/3

* (/ 10.0 3)
3.3333

* (* 10/3 3)
10

* (type-of 10/3)
RATIO

multiple-value-bind, values

truncate returns two values:
* (truncate 12.345)
12
0.34500027
But the following construct compares only the first returned value:
* (= 12 (truncate 12.345))
T
multiple-value-bind can be used of both values are needed;
* (multiple-value-bind (int frac) (truncate 12.345)
  (format t "int = ~d, frac = ~f" int frac)
)
int = 12, frac = 0.34500027
NIL
values can be used to return multiple values:
* (defun one-two-three ()
  (values 1 2 3)
)
ONE-TWO-THREE

* (multiple-value-bind (a b c) (one-two-three)
   (print a)
   (print b)
   (print c)
)
1
2
3
3

describe

* (describe '5)
5
  [fixnum]
* (describe '5.5)
5.5
  [single-float]
* (describe #'describe)
#<FUNCTION DESCRIBE>
  [compiled function]


Lambda-list: (SB-IMPL::OBJECT &OPTIONAL
              (SB-KERNEL:STREAM-DESIGNATOR *STANDARD-OUTPUT*))
Declared type: (FUNCTION (T &OPTIONAL (OR STREAM BOOLEAN))
                (VALUES &OPTIONAL))
Documentation:
  Print a description of OBJECT to STREAM-DESIGNATOR.
Known attributes: unwind, any
Source file: SYS:SRC;CODE;DESCRIBE.LISP

inspect

inspect is the interactive version of describe
* (format (inspect #'inspect))

The object is a FUNCTION named INSPECT.
0. Lambda-list: (SB-IMPL::OBJECT)
1. Ftype: (FUNCTION (T) (VALUES &OPTIONAL))
* (format (inspect #'inspect))

The object is a FUNCTION named INSPECT.
0. Lambda-list: (SB-IMPL::OBJECT)
1. Ftype: (FUNCTION (T) (VALUES &OPTIONAL))
> (inspect 'inspect)

The object is a SYMBOL.
0. Name: "INSPECT"
1. Package: #<PACKAGE "COMMON-LISP">
2. Value: "unbound"
3. Function: #<FUNCTION INSPECT>
4. Plist: NIL

apropos

* (apropos 'print)

M-expressions

M-expressions can be translated to S-expression.
M-expressions were not implemented in common lisp.

gensym

gensym creates a variable name that is guaranteed to be unique in the program.
(defmacro swap (a b) 
    `(let ((tmp ,a))
        (setf ,a ,b  )
        (setf ,b  tmp)
     )
)
    
(defvar a   42)
(defvar b   99)
(swap  a b)
(print a)
(print b)

(defvar tmp 1)
(swap tmp b)
(print tmp)  ; --> Still 1!
(print b  )  ; --> Still 2!
The problem is that tmp is used within the macro and is already a global variable:
* (macroexpand-1 '(swap tmp b))
(LET ((TMP TMP))
  (SETF TMP B)
  (SETF B TMP))
T
With gensym, this problem does not occur:
(defmacro swap (a b) 
  (let ((sym (gensym) ))
    `(let ((,sym ,a))
        (setf ,a ,b  )
        (setf ,b ,sym)
     )
  )   
)

(defvar sym 42)
(defvar a   99)
(swap sym a)
(print a)
(print sym)
* (macroexpand-1 '(swap sym a))
(LET ((#:G490 SYM))
  (SETF SYM A)
  (SETF A #:G490))
T
See also David Wessels Intro to lisp macros.

*

The * seems to represent the last evaluated value:
* (+ 11 3)
14

* (+ * 2)
16

proclaim

According to the common lisp manual, (proclaim '(optimize speed)) informs the compiler to try to use tail-recursion optimization.

declaim

declaim is a macro that makes proclamations recognizable at compile time.
Compare with proclaim and declare.

declare

* (defun f (x)
   (declare (type fixnum x))
   (+ x 1)
)
F

* (f 5)
6

* (f 5.1) ; --> Error The value 5.1 is not of type FIXNUM when binding X

SBCL

Types

The SBCL compiler treats types differently (with more comprehensive type checking) than most other Lisp compilers.

Diagnostic messages

(declaim (sb-ext:muffle-conditions sb-ext:compiler-note))
See also Chapter 4.1 in the manual (2.4.8)

sbcl:*core-pathname*

* sb-ext:*core-pathname*
#P"/usr/bin/../lib/sbcl/sbcl.core"
See also the --core command line option.

sb-kernel:get-lisp-obj-address

In SBCL:
* (sb-kernel:get-lisp-obj-address  42 )
84

* (sb-kernel:get-lisp-obj-address "42")
68745230335

* (sb-kernel:get-lisp-obj-address #'sb-kernel:get-lisp-obj-address)
1386184299
Compare with describe and inspect
See also
  • find-object-by-address
  • system:address-of in CLISP.

Quicklisp

Trying to install Quicklisp for SBCL:
$ cd ~
$ curl -O https://beta.quicklisp.org/quicklisp.lisp
$ gpg --verify quicklisp.lisp.asc quicklisp.lisp
$ sbcl --load quicklisp.lisp
…
* (quicklisp-quickstart:install)
* ; (ql:system-apropos "vecto")
* ; (ql:quickload "vecto")
* (ql:add-to-init-file)
I will append the following lines to #P"/home/rene/.sbclrc":

  ;;; The following lines added by ql:add-to-init-file:
  #-quicklisp
  (let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                         (user-homedir-pathname))))
    (when (probe-file quicklisp-init)
      (load quicklisp-init)))

Press Enter to continue.

#P"/home/rene/.sbclrc"
(exit)
$ (ql:help)
"For help with Quicklisp, see http://www.quicklisp.org/beta/"
But… I should have installed Linedit.

Clojure

Clojure does not have dotted pairs.
Commas are considered whitespace.

See also

Other programming languages etc.

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/developm...', 1758187018, '216.73.216.150', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/development/languages/Lisp/index(1861): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78