【问题标题】:What is the difference between 1 and '1 in Lisp?Lisp 中的 1 和 '1 有什么区别?
【发布时间】:2011-02-27 08:21:49
【问题描述】:

我从来没有真正想过符号是否可以在 Lisp 中成为数字,所以我今天玩弄了它:

> '1
1
> (+ '1 '1)
2
> (+ '1 1)
2
> (define a '1)
> (+ a 1)
2

上面的代码是scheme,但在Common Lisp和Clojure中似乎也大致相同。 1 和引用的 1 有什么区别吗?

【问题讨论】:

标签: lisp clojure scheme common-lisp quote


【解决方案1】:

引用可以防止表达式在以后被计算。例如,以下不是正确的列表:

(1 2 3)

这是因为 Lisp 将 1 解释为一个函数,而事实并非如此。所以必须引用列表:

'(1 2 3)

当你引用一个非常简单的表达式(例如数字)时,Lisp 实际上不会改变它的行为。

Wikipedia: Lisp

【讨论】:

  • 为什么会得到支持?这根本不能回答问题!正确答案是“数字自我评估”,如下所示。
  • 这个答案得到了赞成,因为它解释了为什么数字会评估自己,并提供了指向 Wikipedia 文章的链接以及更多信息。它确实回答了这个问题。
  • 但是,例如,7 维数组和 lambda 形式是自评估对象,而 cons 单元不是,我不确定我是否会称前一个示例比后者。因此,这仅在您将“非常简单的表达式”定义为“自我评估对象”时才有效。 :-)
  • 我是 lisp-y 语言的菜鸟,这个解释 (a) 与 OP 相关并且 (b) 有帮助
【解决方案2】:

数字是self-evaluating objects。这就是为什么您不必担心引用它们,就像您处理列表一样。

符号可以由任何字符串组成。如果你想要名字是单个字符1的符号,你可以说:

(intern "1")

打印|1|,建议另一种输入方式:

'|1|

【讨论】:

  • 我正在使用 clojure 1.1.0...'|1| 计算结果为 |1||1| 带回来...Unable to resolve symbol: |1|
【解决方案3】:

在 Common Lisp 中,'1 是 (QUOTE 1) 的简写。评估时, (QUOTE something) 返回未评估的 something 部分。但是,1 个已评估和 1 个未评估之间没有区别。

所以对读者来说是有区别的:'1 读作 (QUOTE 1) 和 1 读作 1。但是在评估时没有区别。

【讨论】:

  • 这适用于所有自评估表达式
【解决方案4】:

在 Lisp 中,撇号防止符号被计算。不禁止在数字前使用撇号,因为数字代表自己,所以没有必要。但是,与任何其他列表一样,它会自动转换为适当的函数调用。解释器认为这些数字与其值一致。

【讨论】:

  • 函数调用?哪个功能?
  • 我是想写QUOTE(函数调用)!
  • QUOTE 不是函数。在 Lisp 中,撇号会阻止对任何事物的评估。在读取期间,它会转换为 (quote ...)。 QUOTE 是一种特殊形式,它只返回未计算的参数。 Lisp 求值器(解释器或编译器)对此有一个特殊的求值规则。
  • @Rainer 我同意你的看法。我只是说在 Lisp 中,函数调用被写成列表。
【解决方案5】:

正如已经指出的那样,没有区别,因为数字对自己进行评估。您可以使用eval 确认这一点:

(eval 1)  ;=> 1

顺便说一句,这不仅限于数字。事实上,在 Common Lisp 中,大多数事情都会对自己进行评估。只是,除了数字、字符串、符号和列表之外,很少有需要评估的东西。例如,以下工作:

(eval (make-hash-table))  ;equivalent to just (make-hash-table)

【讨论】:

    【解决方案6】:

    嗯,它们实际上是非常不同的。然而'1(quote 1) 完全相同。 (car ''x) 计算为符号 'quote'。

    1 是一个 S 表达式,它是一个数据的外部表示,一个数字 1。说 1 是一个“数字对象”或输入该对象的 S 表达式都是可以接受的.通常说1是实际数字对象的外部表示。

    (quote 1) 是另一个 S 表达式,它是一个 list 的 S 表达式,它的第一个元素是符号“引号”,第二个元素是数字 1。这已经是它所在的位置与函数不同,不同的句法关键字在语言中不被视为对象,也不会对它们进行评估。

    但是,两者都是对象(数据)的外部表示,评估到相同的数据。外部表示为1 的数字,但它们肯定不是相同的对象,相同的代码,相同的数据相同的任何东西,它们只是评估相同的东西。数字对自己进行评估。说它们是一样的就是说:

    (+ 1 (* 3 3))
    

    (if "Strings are true" (* 5 (- 5 3)) "Strings are not true? This must be a bug!")
    

    是“相同的”,它们不是,它们都是不同的程序,只是碰巧终止到相同的值,lisp 形式也是一个程序,形式是一个数据也是一个程序,记住。

    另外,有一次我学到了一个方便的技巧,表明输入时自我评估的数据确实不是符号:

    (let ((num 4))
      (symbol? num) ; ====> evaluates to #f
      (symbol? 'num) ; ====> evaluates to #t
      (symbol? '4) ; ====> evaluates to #f
      (symbol? '#\c) ; #f again, et cetera
      (symbol? (car ''x)) ; #t
      (symbol? quote) ; error, in most implementations
    )
    

    自我评估数据真正评估自己,它们不是某种“预定义符号”。

    【讨论】:

      【解决方案7】:

      在 Lisp 中,quote 阻止计算以下表达式。 'quote 的简写。因此,'1(quote 1) 相同。

      但是,在 Lisp 中,符号永远不能是数字。我的意思是,'abc 是一个符号,但 '123 不是(评估为)一个符号。我认为这是 Lisp 设计的错误。另一种情况是不仅#t#f可以用作布尔表达式。

      【讨论】:

        猜你喜欢
        • 2011-06-02
        • 2018-08-26
        • 2019-01-12
        • 2015-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多