Variables
Local Variables
Local variables behave like in any other language: they are normal lexically scoped variables.
Variables are declared with the let
special operator:
(let ((str "Hello, world!"))
(string-upcase str))
;; => "HELLO, WORLD!"
You can define multiple variables:
(let ((x 1)
(y 5))
(+ x y))
;; => 6
To define variables whose initial values depend on previous variables in the
same form, use let*
:
(let* ((x 1)
(y (+ x 1)))
y)
;; => 2
Dynamic Variables
Dynamic variables are sort of like global variables, but more useful: they are
dynamically scoped. You define them either with defvar
or defparameter
, the
differences being:
defparameter
requires an initial value,defvar
does not.defparameter
variables are changed when code is reloaded with a new initial value,defvar
variables are not.
What does dynamic scoping mean? It means:
(defparameter *string* "I'm global")
(defun print-variable ()
(print *string*))
(print-variable) ;; Prints "I'm global"
(let ((*string* "I have dynamic extent")) ;; Binds *string* to a new value
(print-variable)) ;; Prints "I have dynamic extent"
;; The old value is restored
(print-variable) ;; Prints "I'm global"
In other words, when you redefine the value of a dynamic variable using let
,
the variable is bound to the new value inside the body of the let
, and the old
value is ‘restored’ afterwards.