何时在Lisp中使用'(或引用)?
  在介绍Lisp书的主要部分之后,我仍然无法理解特殊运算符(quote) (或等价'函数)的作用,但这已经遍布我所见过的Lisp代码。 
它有什么作用?
简短回答绕过默认评估规则,不评估表达式(符号或s-exp),将其按照键入的顺序传递给函数。
长答案:默认评估规则
当一个普通的函数被调用时,所有传递给它的参数都会被计算。 这意味着你可以写这个:
(* (+ a 2)
   3)
  依次通过评估a和2来评估(+ a 2) 。在当前变量绑定集中查找符号a的值,然后替换。  说a目前绑定的值3: 
(let ((a 3))
  (* (+ a 2)
     3))
  我们会得到(+ 3 2) ,然后在3和2上调用+,得到5.我们的原始形式现在是(* 5 3)产生15。 
  解释quote已经! 
  好的。  从上面可以看出,所有参数的函数进行评估,因此,如果您想通过符号a ,而不是它的价值,你不希望对其进行评估。  Lisp符号可以将它们的值都加倍,而在其他语言中可能会使用字符串的标记(如密钥散列表)。 
  这就是quote地方。假设你想从一个Python应用程序绘制资源分配,而是在Lisp中进行绘图。  让你的Python应用程序做这样的事情: 
print "'("
while allocating:
    if random.random() > 0.5:
        print "(allocate %d)" random.randint(0, 20)
    else:
        print "(free %d)" % random.randint(0, 20)
    ...
print ")"
给你输出看起来像这样(稍微满意):
'((allocate 3)
  (allocate 7)
  (free 14)
  (allocate 19)
  ...)
  请记住我所说的quote默认规则不适用的quote (“tick”)?  好。  否则会发生的是allocate和free的价值被抬头,我们不希望这样。  在我们的Lisp中,我们希望做到: 
(dolist (entry allocation-log)
  (case (first entry)
    (allocate (plot-allocation (second entry)))
    (free (plot-free (second entry)))))
对于上面给出的数据,下面的函数调用序列将会被创建:
(plot-allocation 3)
(plot-allocation 7)
(plot-free 14)
(plot-allocation 19)
  但是什么关于list ? 
那么,有时候你确实想评估论证。 假设你有一个漂亮的函数来处理一个数字和一个字符串,并返回结果列表。 让我们做一个错误的开始:
(defun mess-with (number string)
  '(value-of-number (1+ number) something-with-string (length string)))
Lisp> (mess-with 20 "foo")
(VALUE-OF-NUMBER (1+ NUMBER) SOMETHING-WITH-STRING (LENGTH STRING))
嘿! 这不是我们想要的。 我们希望有选择地评估一些参数,并将其他参数作为符号。 试试#2!
(defun mess-with (number string)
  (list 'value-of-number (1+ number) 'something-with-string (length string)))
Lisp> (mess-with 20 "foo")
(VALUE-OF-NUMBER 21 SOMETHING-WITH-STRING 3)
  不只是quote ,但backquote quote 
好多了! 可以肯定的是,这种模式在(大部分)宏中非常常见,有特殊的语法来完成这一点。 反引号:
(defun mess-with (number string)
  `(value-of-number ,(1+ number) something-with-string ,(length string)))
  这就像使用quote ,但可以通过用逗号前缀来显式评估一些参数。  结果等同于使用list ,但是如果从宏生成代码,则通常只需评估返回的代码的小部分,因此反引用更适合。  对于较短的列表, list可以更易读。 
  嘿,你忘了关于quote ! 
  那么,这使我们在哪里?  哦,对, quote实际上是做什么的?  它只是简单地返回未评估的参数!  请记住我在开始时对常规功能所说的话吗?  结果发现一些操作符/函数不需要评估它们的参数。  比如IF  - 如果没有被采用,你不希望else分支被评估,对吧?  所谓的特殊操作符和宏一起就是这样工作的。  特殊的操作符也是语言的“公理” - 最少的一组规则 - 您可以通过不同的方式将它们结合在一起来实现Lisp的其余部分。 
  回到quote ,但: 
Lisp> (quote spiffy-symbol)
SPIFFY-SYMBOL
Lisp> 'spiffy-symbol ; ' is just a shorthand ("reader macro"), as shown above
SPIFFY-SYMBOL
比较(在Steel-Bank Common Lisp上):
Lisp> spiffy-symbol
debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD "initial thread" RUNNING   {A69F6A9}>:
  The variable SPIFFY-SYMBOL is unbound.
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.
(SB-INT:SIMPLE-EVAL-IN-LEXENV SPIFFY-SYMBOL #<NULL-LEXENV>)
0] 
  因为当前范围内没有spiffy-symbol ! 
加起来
  quote , backquote (用逗号)和list是用来创建列表的一些工具,它们不仅是值列表,而且正如您看到的,可以用作轻量级(无需定义struct )数据结构! 
如果您想了解更多信息,我推荐Peter Seibel的Practical Common Lisp一本书来学习Lisp的实用方法,如果您已经开始编程。 最后在你的Lisp旅程中,你也会开始使用软件包。 Ron Garret的Common Lisp软件包的白痴指南会给你很好的解释。
快乐黑客!
它说“不要评价我”。 例如,如果您想将列表用作数据,而不是代码,那么您会在其前面添加一个引号。 例如,
  (print '(+ 3 4))打印“(+ 3 4)”,而(print (+ 3 4))打印“7” 
其他人回答这个问题令人钦佩,Matthias Benkard提出了一个很好的警告。
不要使用引用来创建您将要修改的列表。 该规范允许编译器将引用列表视为常量。 通常情况下,编译器会通过在内存中为它们创建单个值来优化常量,然后从常量出现的所有位置引用该单个值。 换句话说,它可以像一个匿名的全局变量一样对待常量。
这可能会导致明显的问题。 如果你修改一个常量,它可能很好地修改了完全不相关代码中相同常量的其他用法。 例如,你可以在某些函数中比较某个变量与'(1 1),并在一个完全不同的函数中,用'(1 1)开始一个列表,然后添加更多的东西。 在运行这些函数时,您可能会发现第一个函数不再适当地匹配事物,因为它现在试图将变量与'(1 1 2 3 5 8 13)比较,这是第二个函数返回的结果。 这两个函数是完全不相关的,但是由于使用了常量,它们相互影响。 即使更疯狂的坏影响也可能发生,就像完全正常的列表迭代突然无限循环一样。
当你需要一个常数列表时使用引号,比如比较。 当您要修改结果时使用列表。
链接地址: http://www.djcxy.com/p/60931.html