How do we set a variable in Lisp?
There are lots of ways to declare variables and change their values in Lisp, each one we use in different situations. For this class, we really only need to worry about 3.
For creating variables that aren’t inside a function, we use the defvar
builtin:
(defvar sym 'hello)
(defvar num 20)
(defvar str "Hello world")
(defvar lst '(hello 20 "hello world"))
We could use defvar
to declare variables inside of functions as well, but Lisp will give us a
warning about this - although it will still work.
For creating variables inside a function, or to create locally-scoped variables, we use let
and let*
(let ((sym 'hello)
(num 20)
(str "Hello world")
(lst '(hello 20 "Hello world")))
(format t "Values: ~s, ~d, ~s, ~a" sym num str lst))
(print "None of those variables are visible here")
We can also use let*
to be able to access previous bindings in the same let
:
(let* ((sym 'hello)
(num 20)
(str "Hello world")
(lst (list sym num str))) ; No need to redeclare the values here
(format t "Values: ~s, ~d, ~s, ~a" sym num str lst))
(print "None of those variables are visible here")
To change the value of a variable, we use the set[f/q]
functions.
The set
function is the most basic of the 3 ways to set a value in Lisp. We simply pass it an atom
and a value, and it binds that value to the symbol:
(set 'x 10)
The setq
tool means “set quoted”. It’s similar to set
, except that we don’t have to quote the symbol
being passed to it:
(setq x 10)
Now, unlike set
, if we call setq
with a variable that doesn’t exist yet, Lisp will give us a
warning. So if you need to, you can use set
to declare variables, but setq
will warn you against it.
The setf
tool means “set field”. It behaves the same as setq
when trying to set just the value of a
variable:
(let ((x 10) (y 20))
(setq x 20)
(setf y 30))
Will do the same thing. However, we can also use setf
to set the values inside a list:
(defvar lst '(1 2 3 4 5))
(setq (car lst) 10) ; This will give an error
(setf (car lst) 10) ; This will mutate the list
(print lst) ; '(10 2 3 4 5)