【问题标题】:Why does (find-if #'consp '('notdefinedsymbol)) => 'NOTDEFINEDSYMBOL?为什么 (find-if #'consp '('undefined symbol)) => 'NOT DEFINED SYMBOL?
【发布时间】:2020-03-03 22:18:51
【问题描述】:

这段代码来自emacs缓冲区slime-repl sbcl

CL-USER> (consp 'notdefinedsymbol)

CL-USER> (find-if #'consp '('notdefinedsymbol))

'未定义符号

如果 consp 返回 nil 那么为什么 find-if 会像 consp 返回一个真值一样呢?

【问题讨论】:

    标签: common-lisp quote


    【解决方案1】:

    (consp 'notdefinedsymbol) consp 在操作符位置是#'consp 函数的符号,因此它的参数(quote notdefinedsymbol),缩写为'notdefinedsymbol 需要在应用之前进行评估。 (quote x) 对数据 x 进行赋值,因此在我们的例子中,参数变为符号 notdefinedsymbol。它不是cons,而是symbolp,因此结果是nil

    第二个你有(find-if #'consp '('notdefinedsymbol)),因为find-if是一个函数,它会评估它的参数。 #'consp 计算为函数对象,'('notdefinedsymbol)(quote ((quote notdefinedsymbol))) 的缩写,计算结果。一如既往,它评估了它的论点((quote notdefinedsymbol))。它是一个包含一个元素的列表,它本身就是一个包含两个元素的列表,符号quotenotdefinedsymbol。由于(consp '(quote notdefinedsymbol) ; ==> t find-if 评估为(quote notdefinedsymbol) 并且一些CL 打印机将缩写两个元素的列表,其中第一个元素是quote,其方式与阅读器宏相同并打印'notdefinedsymbol,但它仍然是一个列表两个元素,因为它不是代码,而是数据。

    您的错误当然是嵌套引号。如果你这样做了,你会得到预期的结果:

    (find-if #'consp '(notdefinedsymbol)) ; ==> nil
    

    【讨论】:

      【解决方案2】:

      (consp 'a) - 首先评估函数参数。所以我们有:'a 计算结果为:a。那是一个原子,因此是NIL

      (find-if #'consp '('a)) 也首先评估参数。但是对于列表的第一个参数,它测试'a 是否是一个缺点。是的,因为那是(quote a)(只评估列表的外部',而不是a前面的内部,因此'a

      a = notdefinedsymbol.

      【讨论】:

        【解决方案3】:

        您的电话:(find-if #'consp '('not-defined-symbol)) 与(即由读者扩展为)(find-if (function consp) (quote ((quote not-defined-symbol)))) 相同。参数(quote ((quote not-defined-symbol))) 被评估为列表((quote not-defined-symbol))(即一个包含两个符号quotenot-defined-symbol 的列表的列表)。 Find-if 遍历那个外部列表,测试内部,这是一个缺点,consp,它说 true,然后返回它。

        你想做的最有可能是:(find-if #'consp '(not-defined-symbol))(find-if (function consp) (quote (not-defined-symbol))相同。注意:没有嵌套引号。

        查看the docs for quotethe CLHS chapter about evaluation 以获得更好的理解。

        【讨论】:

          猜你喜欢
          • 2019-08-13
          • 2021-09-16
          • 2022-12-02
          • 1970-01-01
          • 2023-01-29
          • 2021-01-10
          • 1970-01-01
          • 2016-06-29
          • 1970-01-01
          相关资源
          最近更新 更多