bbarker
bbarker

Reputation: 13088

In Lisp, why do we need to use a list function to return a list?

I would have thought this would work:

(defun list-of-things (thing1 thing2 thing3)
  "returns a ???"
  '(thing1 thing2 thing3))

But this is actually what is needed to return a list:

(defun list-of-things (thing1 thing2 thing3)
  "returns a list" 
  (list thing1 thing2 thing3))

Upvotes: 2

Views: 533

Answers (3)

Rainer Joswig
Rainer Joswig

Reputation: 139261

Lisp evaluation rules

You need to understand the evaluation rules of Common Lisp first:

  • the symbol a is a variable and evaluates to its value
  • the list (operator ... ) is a form. There are four types of forms: function call, macro form, special form, lambda form
  • everything else evaluates to itself: numbers, strings, arrays, hash tables, characters, CLOS objects, structures, ...

There is a fixed number of special operators. One is QUOTE. (QUOTE ...) means that the object inside does not get evaluated. '(...) is another notation for (QUOTE ...) - it's easier to write.

So symbols and lists have a role: they are variables and forms.

What if you want to have literal symbols and literal lists? Answer: you have to quote them.

Remember: If you quote a list, then the whole list including its elements is literal data and not evaluated.

Examples:

A global variable defined:

CL-USER 18 > (defvar *a* 42)
*A*

The symbol *a* is quoted and thus the form (QUOTE *A*) evaluates to the symbol:

CL-USER 19 > '*a*
*A*

Inside quoted lists everything is literal data and not evaluated.

CL-USER 20 > '(*a*)    ; same as (QUOTE (*A*))
(*A*)

The unquoted symbol is evaluated as a variable:

CL-USER 21 > *a*
42

A function call has all its arguments evaluated:

CL-USER 22 > (list *a*)
(42)

A backquote expression allows certain elements in a list to be evaluated using the comma prefix:

CL-USER 23 > `(41 ,*a* (+ 1 *a*) (+ 1 ,*a*) ,(+ 2 *a*))
(41 42 (+ 1 *A*) (+ 1 42) 44)

Summary

When you want to return a list from a function, you can:

  1. return a fixed literal list

  2. or compute a new list based on some objects by constructing the list with the usual operators: CONS, LIST, APPEND, ...

  3. or use a backquote expression which gets expanded by the Lisp reader into an implementation specific version of 2.

Upvotes: 4

Numbra
Numbra

Reputation: 642

Those are two different things, and a central concept in Lisp languages.

The syntax '(a b c) is a shorthand for (quote (a b c)) and quote is a special form that returns its argument unevaluated. In that case, it would be list, containing three symbols.

On the other hand, list is a normal function, it evaluates its arguments and return the list of their values.

To go a bit more in-depth: before evaluating any expression, the code has to be read. The part that is very specific to Lisp (and, in fact, even more so with Common Lisp) is that the "parser" is actually just a Lisp function, returning Lisp objects. Those objects are then given to the "evaluator", which evaluates them:

  • When reading the characters '(thing1 thing2 thing3), the reader knows that ' is a reader-macro, and so it reads (quote (thing1 thing2 thing3)). This is a list of two elements, a symbol and another list of three symbols. This list is then given to the evaluator: it knows that quote is a special form that returns its argument unevaluated, and so it simply returns the list (thing1 thing2 thing3), given to it by the reader.
  • On the other hand, when reading (list thing1 thing2 thing3), the reader also reads this as a list (this time, containing 4 symbols) that it then gives to the evaluator. Now, the evaluator sees that the first symbol is list, a function, and so it evaluates the arguments (i.e. it determines what the symbols thing1 ... are bound to), passes them to the list functions, etc.

All this is possible because Lisp code is defined in terms of Lisp objects (such as lists, etc). After the "parsing" (actually called reading) phase, the evaluator is really given an actual Lisp object to evaluate. Things are of course slightly more complicated when talking about compilation, etc, but the general idea is the same. The quote operator, abbreviated ', is a way to "directly" access the thing created by the reader, and to "bypass" evaluation.

Upvotes: 6

Yongjian P.
Yongjian P.

Reputation: 251

The list function is used for creating lists. They called LISP because it’s for LISt Processing. Also, because Lisp functions are written as lists, they can be processed exactly like list.

Upvotes: 0

Related Questions