English 中文(简体)
In Lisp (Clojure, Emacs Lisp), what is the difference between list and quote?
原标题:

From reading introductory material on Lisp, I now consider the following to be identical:

(list 1 2 3)

 (1 2 3)

However, judging from problems I face when using the quoted form in both Clojure and Emacs Lisp, they are not the same. Can you tell me what the difference is?

问题回答

The primary difference is that quote prevents evaluation of the elements, whereas list does not:

user=>  (1 2 (+ 1 2))
(1 2 (+ 1 2))
user=> (list 1 2 (+ 1 2))
(1 2 3)

For this reason (among others), it is idiomatic clojure to use a vector when describing a literal collection:

user=> [1 2 (+ 1 2)]
[1 2 3]

In Common Lisp, quoted objects are constant literal data. The data is not evaluated. You should not modify this data, as the consequences are undefined. Possible consequences are: modification of shared data, attempt to modify read-only data, an error might be signalled, it might just work, shared data, ...

Literal lists:

 (1 2 3)

Above is a constant list, which will be constructed by the reader and evaluating to itself, because it is quoted. If it appears in Lisp code, a compiler will embed this data somehow in the FASL code.

(quote (1 2 3)) is another way to write it.

(list 1 2 3)

this is a call of the Common Lisp function LIST with three arguments 1, 2 and 3. Each of the arguments will be evaluated. Since they are numbers, they evaluate to themselves. When evaluated the result is a fresh new list (1 2 3).

Data sharing in compiled code

Imagine in a Lisp file the following four definitions:

(defparameter *list1* (list 1 2 3))
(defparameter *list2* (list 1 2 3))
(defparameter *list3*  (1 2 3))
(defparameter *list4*  (1 2 3))

Then we compile and load the file.

! (eq *list3* *list4*) now may evaluate to either T or NIL depending on the implementation and compiler settings !

Reason: in Common Lisp the Lisp compiler may share structure of literal lists (!) if they are similar. The compiler detects that here the lists are similar and will allocate only one list. Both variables *list1* and *list2* the will point to this one list.

All other EQ (object equality) comparisons of two of the above lists will return NIL.

Notations for some other data structures:

 (1 . 2)            and  (cons 1 2)            ; cons cell

 #(1 2 3)           and  (vector 1 2 3)        ; vector

 #S(FOO :a 1 :b 2)  and (make-foo :a 1 :b 2)   ; structure

One is the literal data and the other is a function call that constructs such a data structure.

Quoted lists (e.g. (1 2 3)) should be treated carefully (generally as read-only). (see SO answers When to use quote in Lisp and When to use quote in Lisp).

(list 1 2 3) will "cons" up a fresh list, independent of all others.

You can see an example of a pitfall of using quoted lists in the manual for nconc.

And, as you probably know, when you call list - the arguments will obviously be evaluated versus the contents of a quoted list. And quote takes a single argument, versus lists variable number of arguments.

(list (+ 1 2) 3)     -->  (3 3)
(quote ((+ 1 2) 3))  -->  ((+ 1 2) 3)

Their relation can be analogous to function invocation with function name and funcall.

When you have no idea what function you ll get at runtime, you use funcall.

When you have no idea what element you may get at runtime, your use list.


For people like me who get confused because of existence of backquote and count it as quote tacitly.

backquote is not quote

It s a reader-macro that expands into quote, list or others:

(macroexpand   (1 2));=>  (1 2)
(macroexpand  `(1 2));=>  (1 2)
(macroexpand  `(1 ,2));=> (list 1 2)
(macroexpand  `(1 ,@foo));=> (cons 1 foo)
(macroexpand  `(1 ,@foo 2));=> (cons 1 (append foo  (2)))




相关问题
Lisp code called from Java

Long story: I am doing a project for my functional programing class, and I thought of writing an AI controller in Lisp, for the Mario AI competition. I was looking over frameworks/libraries/ways of ...

Emacs, Zen-Coding mode, and Putty

I use emacs via Putty and since Putty doesn t send certain key combinations to the remote console I generally need to re-bind them to other key combinations. After installing the amazing Zen-Coding ...

In Which Cases Is Better To Use Clojure? [closed]

I develop in Lisp and in Scheme, but I was reading about Clojure and then I want to know, in which cases is better to use it than using Lisp or Scheme? Thanks

lambda-gtk negative pointer

I was trying to write my own put-pixel on (Gdk) pixbuf in Lisp. When I finally realized how I can operate on C pointers in CL, new obstacle came along - (gdk:pixbuf-get-pixels pb) returns me negative ...

Is there a common lisp package naming convention?

I have created some of my own user packages and have run into a name clash. In Java, the naming convention is to use your domain name in the package name: e.g. import com.example.somepackage;. Are ...

SOAP request from within an AutoLISP/AutoCAD macro

We have built a webservice for a client that uses AutoCAD. They have a macro that runs in AutoCAD that builds a SOAP request. But they have not figured out how to actually send() the soap request to ...

热门标签