【问题标题】:Clojure - Quoting ConfusionClojure - 引用混淆
【发布时间】:2012-01-03 04:32:22
【问题描述】:

对不起,这个非常模糊的标题:)

我是宏的新手,无法理解这两个语句之间的区别:

`(+ 1 2 ~(+ 2 3)) ; => (clojure.core/+ 1 2 5)
'(+ 1 2 ~(+ 2 3)) ; => (+ 1 2 (clojure.core/unquote (+ 2 3)))

当我在不加引号的情况下运行它们时,它们看起来除了排位赛之外几乎完全相同?

`(+ 1 2 (+ 2 3)) ; => (clojure.core/+ 1 2 (clojure.core/+ 2 3))
'(+ 1 2 (+ 2 3)) ; => (+ 1 2 (+ 2 3))

所以基本上我对 ` vs ' 感到困惑。我的理解是他们都引用了列表中的所有内容,这就是为什么我不确定为什么不引用的行为会有所不同。基本上 ` 的行为方式与我期望 ` 和 ' 的行为方式相同。

谢谢!

【问题讨论】:

    标签: macros clojure lisp


    【解决方案1】:

    简短的回答是,取消引用仅在反引号内有效。在正常的引用表达式中,所有内容——包括~ 和内部/后面的所有内容——都按原样传递,而在反引号表达式中,~ 内部/后面的所有内容都被评估(但其他所有内容都保持未评估)。所以,不,不是反引号表达式中的所有内容都未计算 - 您可以在其中使用 ~,将其用作一种模板,您可以在其中使用 ~“填充空白”。

    编辑:引用(双关语)与您的问题相关的documentation

    引用:

    Quote (')
    'form => (quote form)
    

    和(来自special forms 部分):

    (引用形式)产生未评估的形式。

    user=> '(a b c)
    (a b c)
    

    请注意,没有尝试调用函数 a。返回值 是 3 个符号的列表。

    语法-引用(也叫准引用、反引号):

    对于 Lists/Vectors/Sets/Maps,syntax-quote 建立了一个模板 对应的数据结构。模板内,不合格 形式表现得好像递归地引用了语法,但形式可以是 通过使用 unquote 限定它们来免除此类递归引用 或 unquote-splicing,在这种情况下,它们将被视为表达式 并在模板中被它们的值或值序列替换, 分别。

    【讨论】:

    • 您还可以提及伟大的论文Quasi Quotation in Lisp by Alan Bawden
    • Daimrod,是的,感谢您的链接! (初学者注意:其他 Lisp 方言和 Clojure 之间存在一些差异。例如,在 CL 和论文中,,(Clojure 中的空格)用于取消引用。此外,在 CL 中,, 在反引号表达式无效(通常是阅读器错误)。)
    • 谢谢,我没有意识到取消引用是为语法引用保留的。这绝对解释了结果。我正在阅读 Clojure 的乐趣,我在宏章节中暂停了实验并尝试理解这些东西,所以我可能在本章中错过了进一步的解释 :)
    【解决方案2】:

    尝试在前两个表达式的结果上运行eval。第一个,带有`,“扩展”到(+ 1 2 3),很好地评估为6。第二个,带有',“扩展”到(+ 1 2 (unquote (+ 1 2))),并且取消引用在该上下文中无效,因为您不再在里面的报价!所以这完全无法评估。

    '和`之间基本上有两个区别:

    • `命名空间限定一切
    • ` 允许取消引用

    【讨论】:

      猜你喜欢
      • 2012-08-30
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 2020-04-14
      • 1970-01-01
      相关资源
      最近更新 更多