在Racket中,'(撇号)是什么?

4

我对 racket 中的 ' 符号的含义有些困惑。在我的理解中,同一符号具有不同的含义。看下面两个简单的例子:

list

返回一个新分配的列表,其中包含 vs 作为其元素。

> (list 1 2 3 4)
'(1 2 3 4)

quote

该函数生成一个常量值,对应于数据(即程序片段的表示),但不包括其词法信息、源位置等。引用对、向量和框架是不可变的。

> '(1 2 3 4)
'(1 2 3 4)

所以我的问题是: 单引号符号 ' 是否有两个含义(一个是符号,一个是列表),或者它们是相同的数据类型,list 实际上返回一个带引号的常量值?如果是第二种情况,为什么这样可以工作:
> '(+ (- 2 13) 11)
'(+ (- 2 13) 11)

> (eval (list + (- 2 13) 11))
0

(还有(eval '(+ (- 2 13) 11))可以正常工作并正确评估为0

但这个不行:

> (list + (- 2 13) 11)
'(#<procedure:+> -11 11)

> (eval '(#<procedure:+> -11 11))
. read: bad syntax `#<'

相关内容可能包括: Lisp / Scheme中的撇号是什么?


1
(eval '(#<procedure:+> -11 11)) 无法工作的原因是 #<procedure:+> 无法被读回。然而,使用 quasiquote 和 unquote,(eval (quasiquote ((unquote +) -11 11))) 可以工作。使用简写可以写成 (eval `(,+ -11 11)) - Alex Knauth
2个回答

7

您可能对 #lang racket 的默认打印方式感到困惑,与几乎所有其他交互式lisp环境不同。如果您在DrRacket中选择另一种语言,例如R5RS,您会发现它会打印:

> (list 1 2 3 4)
(1 2 3 4)

即,将数字1 2 3 4 应用于运算符list的结果是生成一个包含这些数字的列表,这正是(1 2 3 4)的解释。
因此,对于您的情况,“Lisp / Scheme中的'(撇号)是什么?”的答案也是有效的,'anything只是(quote anything)的缩写。

好的。谢谢您的澄清。但是为什么(eval (list + (- 2 13) 11))的结果是0呢?难道函数调用不仅仅是函数名首先出现,然后是其参数的列表吗?因为(eval (list 1 2 3 4))会导致错误1不是过程 - ferdynator
3
“函数调用仅是先列出函数名,然后跟随其参数的列表吗?”几乎正确但并不完全。在该语言中所评估的是一个表格,即第一个参数为函数的特殊列表。您的第一个示例有效,因为“+”是一个函数的名称,并且(list + (-2 13) 11)的结果是列表(<the function +> -11 11)(对list的每个参数进行了评估)。在您的第二个示例中,(list 1 2 3 4)的结果是列表(1 2 3 4),它不是一个表格,因为1不是一个函数。 - Renzo

4

>是REPL(读取-求值-输出循环)的标志。

首先,您在REPL提示符处键入的任何表达式都会被读取 - 转换为某种内部抽象语法树表示形式。然后对键入的表达式的内部表示进行求值 - 即找到其值。然后将结果打印出来。

当我们输入时:

> (list 1 2 3 4)

输入的表达式被读取为嵌套结构,我们将其写成:
[LIST | [1 | [2 | [3 | [4 | NIL ]]]]]

根据通常将列表表示为数据对和列表其余部分的方式(这里用 [a | b] 表示一个 ab 的数据对),则上述结构被评估。由于它的第一个元素是 LIST,导致调用指定参数的 list 函数,并生成一个新的列表结构,可以表示为:
[1 | [2 | [3 | [4 | NIL ]]]]

然后它被打印出来,通常是作为(1 2 3 4),但Racket选择将其打印为'(1 2 3 4)。顺便说一句,它不能被评估,因为1不能被调用。
接下来是引用表达式'(1 2 3 4),它被读作(quote (1 2 3 4))。它被转换成
[QUOTE | [ [1 | [2 | [3 | [4 | NIL ]]]] | NIL ]]

当按照quote的评估规则进行评估时,它会返回接收到的数据。我们将其表示为

[1 | [2 | [3 | [4 | NIL ]]]]

这就是它们两个之间相似的原因。无论我们是创建一个包含1、2、3和4的新列表,还是在读取过程中将其创建出来,以便通过quote直接返回,结果都是相同的。

谢谢您的澄清。我认为结合之前的回答,我终于明白了 :) - ferdynator
1
不客气。 :) 有些人声称这是Scheme最令人困惑的部分。当然,除了call/cc之外。 :) - Will Ness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接