【问题标题】:What is ' (apostrophe) in Racket?什么是球拍中的'(撇号)?
【发布时间】:2016-02-20 03:55:57
【问题描述】:

我对@9​​87654324@ 登录球拍的含义有些困惑。在我看来,同一个符号有不同的含义。看下面两个简单的例子:

list

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

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

quote

产生一个与 datum 对应的常量值(即程序片段的表示),没有其词法信息、源位置等。引号对、向量和框是不可变的。

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

所以我的问题是: ' 符号是否有 2 个含义(一个 符号 和一个 list)或者它们是相同的数据类型,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 `#<'

相关的可能: What is ' (apostrophe) in Lisp / Scheme?

【问题讨论】:

  • (eval '(#&lt;procedure:+&gt; -11 11)) 不起作用的原因是 #&lt;procedure:+&gt; 不能被读回。但是,使用 quasiquote 和 unquote,(eval (quasiquote ((unquote +) -11 11))) 有效。使用写成(eval `(,+ -11 11))的简写。

标签: functional-programming scheme racket quote repl-printed-representation


【解决方案1】:

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

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

也就是说,运算符 list 应用于数字 1 2 3 4 的结果是生成这些数字的列表,这正是 (1 2 3 4) 的解释。

所以,答案是 What is ' (apostrophe) in Lisp / Scheme? 也适用于您的情况,'anything 只是 (quote anything) 的缩写。

【讨论】:

  • 好的。谢谢你的澄清。但是为什么(eval (list + (- 2 13) 11)) 的计算结果为0?函数调用只不过是函数名的列表,然后是它的参数吗?因为(eval (list 1 2 3 4)) 导致错误1 is not a procedure
  • “函数调用仅仅是函数名的列表,然后是其参数吗?”几乎正确但不完全正确。在语言中,评估的是一个 form,即第一个参数是函数的特殊列表。您的第一个示例有效,因为“+”是函数的名称,(list + (- 2 13) 11) 的结果是列表(&lt;the function +&gt; -11 11)list 的每个参数都被评估)。在您的第二个示例中,(list 1 2 3 4) 的结果是列表(1 2 3 4),它不是一个表单,因为1 不是一个函数。
【解决方案2】:

&gt; 是 REPL 的标志 - 读取-评估-打印循环。

首先,您在 REPL 提示符下键入的任何表达式都是 read - 转换为一些内部抽象语法树表示。然后,输入表达式的这个内部表示被 求值 - 即找到它的值。然后打印结果。

当我们输入时

> (list 1 2 3 4)

键入的表达式被读取为嵌套结构,我们把它写成

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

根据通常将列表表示为数据对和列表的其余部分(此处将一对ab 显示为[a | b])。

然后评估上述结构,因为它的第一个元素是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 的新列表;或者我们让它作为 read 进程的一部分被创建,所以它被quote逐字返回;结果是一样的。

【讨论】:

  • 感谢您的澄清。我想结合前面的答案我终于明白了:)
  • 不客气。 :) 有人声称这是 Scheme 中最令人困惑的部分。当然除了通话/抄送。 :)
猜你喜欢
  • 1970-01-01
  • 2010-12-05
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 2023-04-07
  • 2021-04-26
相关资源
最近更新 更多