Common Lisp supports two kinds of variables: lexical and dynamic roughly to “local” and “global” in other language
one hand : a variable can hold values of any type and the values carry type information that can be used to check types at runtime.
Common Lisp is dynamically typed – type errors are detected dynamically.
Common Lisp is a strongly typed language in the sense that all type errors will be detected – there’s no way to treat an object as an instance of a class that it’s not
LET
(let (variable*)
body-form*)
(defun foo (x)
(format t “Parameter: ~a~%” x)
(let ((x 2))
(format t “Outer LET: ~a~%” x)
(let ((x 3))
(format t “Inner LET: ~a~%” x))
(format t “Outer LET: ~a~%” x))
(format t “Parameter: ~a~%” x))
LET*
the initial value forms for each variable can refer to variables introduced earlier in the variables list ,thus ,you can write the following:
(let* ((x 10)
(y (+ x 10)))
(list x y))
lexical variables and closures
dynamic,a.k.a special variables
Common Lisp provides two ways to create global variables: DEFVAR and DEFPARAMETER.
The difference between the two forms is that DEFPARAMETER always assigns the initial
value to the named variable while DEFVAR does so only if the variable is undefined.
可用let方式修改dynamic variables的值,或者在某个域中用另外一个值代替
(let ((*standard-output* *some-other-stream*))
(stuff))
(defun foo ()
(format t “X: ~d ~%” *x*))
(defun bar()
(foo)
(let ((*x* 20)) (foo))
(foo))
constans variables which defined with DEFCONSTANT defconstant
like (defconstant name initial-value-form [ documentation-string])
follow naming convention of using names starting and ending with + for constants
assignment
(setf place value) e.g (setf x 10)
setf can also assign to multiple places e.g (setf x 1 y 2)
more complex using: (setf x (setf y (random 10))) because setf returns the newly assigned value
generalized assignment
Common Lisp supports composite data structures: array hash tables lists user-defined data structures
Simple variable: (setf x 10)
Array: (setf (aref a 0) 10)
Hash table: (setf (gethash ‘key hash) 10)
Slot named ‘field’: (setf (field o) 10)
(incf x) ≡ (setf x (+ x 1))
(decf x) ≡ (setf x (- x 1))
(incf x 10) ≡ (setf x (+ x 10))
(rotatef a b) swaps the values of the two variables and returns NIL
(rotatef a b c) equivalent (let ((tmp a)) (setf a b b c c tmp) nil)
equivalent to this: (let ((tmp a)) (setf a b b tmp) nil)
while shiftf is more useful
the last argument provides a value to its left argument
(shiftf a b 10) equivalent (let (setf a b c 10) nil)