gpt4 book ai didi

lisp - 什么时候在Lisp中使用'(或引用)?

转载 作者:太空宇宙 更新时间:2023-11-03 19:01:35 25 4
gpt4 key购买 nike

在看完了一本介绍性的Lisp书籍的主要部分之后,我仍然无法理解特殊运算符(quote)(或等效的')函数的作用,但是我看到的所有Lisp代码都是这样的。
它是做什么的?

最佳答案

简短的回答
绕过默认的求值规则,不求值表达式(symbol或s-exp),将其完全按类型传递给函数。
长答案:默认的评估规则
当调用一个正则函数(稍后我将讨论这个函数)时,传递给它的所有参数都将被求值这意味着你可以写下:

(* (+ a 2)
3)

它依次通过评估 (+ a 2)和2来评估 a。符号 a的值在当前变量绑定集中查找,然后替换假设 a当前绑定到值3:
(let ((a 3))
(* (+ a 2)
3))

我们得到 (+ 3 2),然后在3和2上调用+得到5我们最初的形式现在是 (* 5 3)产生15。
已经解释了!
好吧如上所示,函数的所有参数都是求值的,因此如果要传递符号 quote而不是其值,则不需要求值lisp符号可以同时用作它们的值和其他语言中使用字符串(如哈希表的键)的标记。
这就是 a的来源。假设您想绘制来自Python应用程序的资源分配,而不是在Lisp中进行绘制让您的python应用程序执行以下操作:
print("'(")
while allocating:
if random.random() > 0.5:
print(f"(allocate {random.randint(0, 20)})")
else:
print(f"(free {random.randint(0, 20)})")
...
print(")")

输出如下所示(稍微美化):
'((allocate 3)
(allocate 7)
(free 14)
(allocate 19)
...)

还记得我说过的导致默认规则不适用的 quote(“tick”)吗?很好。否则会发生的是, quoteallocate的值被查找,我们不希望这样在我们的口齿不清中,我们希望:
(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)

但是 free呢?
好吧,有时候你真的想评估论点。假设你有一个漂亮的函数处理一个数字和一个字符串并返回一个结果列表…东西。让我们错误地开始:
(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)

不仅 list,而且 quote
好多了!顺便说一下,这种模式在(主要是)宏中非常常见,因此有专门的语法来实现这一点。反面引用:
(defun mess-with (number string)
`(value-of-number ,(1+ number) something-with-string ,(length string)))

这就像使用 backquote,但是有选择通过用逗号预置它们来显式地评估某些参数。其结果相当于使用 quote,但如果从宏生成代码,则通常只希望计算返回的代码的一小部分,因此后引号更适合对于较短的列表, list可读性更强。
嘿,你忘了 list
那么,这给我们留下了什么?哦,对了, quote实际上是做什么的?它只是返回其参数未评估还记得我刚开始说的常规功能吗?结果发现,一些运算符/函数不需要计算它们的参数比如——如果不使用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]

因为在当前范围内没有 quote
总结
spiffy-symbolquote(带逗号)和 backquote是一些用于创建列表的工具,这些列表不仅是值列表,而且可以用作轻量级(无需定义 list)数据结构!
如果您想了解更多,我建议您使用peter seibel的书 Practical Common Lisp作为学习lisp的实用方法,如果您已经对编程很感兴趣的话。最终在你的lisp之旅中,你也会开始使用软件包。罗恩·加雷特的“aa”会给你很好的解释。
快乐黑客!

关于lisp - 什么时候在Lisp中使用'(或引用)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46979329/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com