Declaring and modifying variables in Common Lisp

Table of Contents

toggle-theme.png

Question:

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.

Declaring top-level variables

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.

Declaring local variables

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")

Mutating existing variables

To change the value of a variable, we use the set[f/q] functions.

set

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)

setq

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.

setf

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)

Author: Philip Dumaresq

Email: phdumaresq@protonmail.com

Created: 2021-03-13 Sat 19:09