Lisp quest discovering a parenthesis world

Lisp lists basics - the list function

In a previous post we have talked about creating lists in Lisp using the quote special operator. Now we will introduce the list function that allows us to build mutable lists in the canonical Lisp way. By the end of this post you will also understand why building a list with the list function is so much different from doing it using the quote special operator.

Creating a list with the list function

Using the list function to is straightforward: just add it as the first element of a list (a couple of parenthesis with elements inside) followed by the elements of the list you want inside it.

* (list 1 2 3)
(1 2 3)

As you can see, the Lisp REPL will return us the newly created list with the elements inside. At this point you may be wondering why you should use the list function rather than the quote special operator.

list function VS quote operator

At first sight, the list function is not producing nothing different than before.

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

* (list 1 2 3)
(1 2 3)

Given a sequence of numbers, it returns a list containing those numbers. The only noticeable difference is the the missing parenthesis around the numbers, but the result looks the same as with quote.

Let’s try with something more interesting.

* '((+ 1 2) 4)
((+ 1 2) 4)

* (list (+ 1 2) 4)
(3 4)

What is happening here is clear: using the list function, every parameter of the function is being evaluated before it is added to the list. The quote special operator, instead, is creating the list as is without evaluating its elements.

This behaviour is even more explicit if we try creating a list of characters.

* '(a b c)
(A B C)

* (list a b c)
debugger invoked on a UNBOUND-VARIABLE in thread
#<THREAD "main thread" RUNNING {1000510083}>:
The variable A is unbound.
...

Using the quote special operator, a list is created and its elements are converted to symbols.1 Intead, using the list function, the Lisp compiler tried to evaluate every element starting from a, resulting in an error: an a variable does not exists in this scope.

You can always create the same quoted list using the list function quoting each element.2

* (list 'a 'b 'c)
(A B C)

When to use quote or list?

Creating a list is different from quoting a list, so you can not use them interchangeably. You should use the list function when you want the list elements being evaluated before the creation of the list. Moreover, creating a new list means creating new elements for it. Instead, with the quote operator you have a list of symbols, and this is something completely different from a plain old list.

  1. Don’t worry, we will talk about symbols in another post. The conversion to symbols is also the reason behind why you should not modify a quoted list: symbols could be shared by the compiler between different lists… 

  2. This is exactly what the quote special operator does: it quotes each element in the given list.