【问题标题】:Clojure - difference between ' (apostrophe) and ` (backtick)Clojure - '(撇号)和`(反引号)之间的区别
【发布时间】:2013-07-21 23:24:45
【问题描述】:

我对 Clojure 还很陌生,我不确定我是否完全理解 Clojure 中撇号和反引号之间的区别。

(def x 5)

;; Question 1
(+ x x)  ;; evaluates to 10
'(+ x x) ;; evaluates to (+ x x)
`(+ x x) ;; evaluates to (clojure.core/+ user/x user/x)

;; Question 2
`(~+ ~x ~x) ;; evaluates to (#<core$_PLUS_ clojure.core$_PLUS_@32ee28a9> 5 5)
  1. 如果我错了,请纠正我,但在我看来,撇号会阻止所有符号(即 + 和 x)解析为它们各自的 var,而反引号允许符号解析为它们的 var(但不计算到 var 中的值)。这准确吗?
  2. 这里的非引号符号 (~) 究竟是做什么的?是否将 var 评估为其实际值(即函数对象的 + 符号和数字对象的 x 符号)?如果您可以用 Clojure 的 READ-COMPILE-EVAL 阶段来解释这一点,那也会很有帮助。

【问题讨论】:

    标签: clojure read-eval-print-loop apostrophe backticks


    【解决方案1】:

    当您使用' 引用集合时,符号名称将完全按照您输入的方式引用。

    '(+ x x) 
    => (+ x x)
    (map namespace *1)
    => (nil nil nil)
    '(bingo/+ lara/y user/z)
    => (bingo/+ lara/y user/z)
    (map namespace *1)
    => ("bingo" "lara" "user")
    

    当您使用反引号引用集合时,它会尝试查找每个符号的命名空间。如果找不到,则使用当前命名空间。如果您指定命名空间,它的工作方式与带有限定命名空间的' 相同。

    `(+ x x)
    = > (clojure.core/+ user/x user/x)
    (map namespace *1)
    => ("clojure.core" "user" "user")
    

    当您在` 中使用~ 时,该表单将不被引用。这有助于构建宏,其中宏使用定义它的命名空间中的符号以及使用它的命名空间中的符号。

     `(+ ~'x x)
     => (clojure.core/+ x user/x)
     `(+ ~x x)
     => (clojure.core/+ 3 user/x)
    

    最后,你可以取消引用一整套被引用的东西拼接。

     `(+ ~@`(x x))
     => (clojure.core/+ user/x user/x)
    

    看到xes 可能已作为命名空间限定符号列表传递,并已拼接到另一个列表中。您不能在反引号引用的集合之外使用 ~~@

    【讨论】:

    【解决方案2】:

    反引号是 Clojure 术语中的语法引用,请参阅 http://clojure.org/reader 的描述。

    在阅读过程中,`(~+ ~x ~x) 扩展为生成可以引用词法环境的列表的形式。然后编译器编译这段代码。让我们看看 `(~+ ~x ~x) 扩展成什么,并在前面加上引号:

    user=> '`(~+ ~x ~x)
    (clojure.core/seq (clojure.core/concat (clojure.core/list +) (clojure.core/list x) (clojure.core/list x)))
    

    如果您只是在文本编辑器中插入此表单而不是`(~+ ~x ~x),它将使用+ 函数和两个x 构建列表。因此,`(~+ ~x ~x) 扩展为构建特定结构列表的 Clojure 代码。

    反引号是 Clojure 数据(列表、数组等)的一种模板语言。

    【讨论】:

    • “syntax-quote”到底是什么意思?
    • 这只是 Clojure 文档中的一个词。另请参阅stackoverflow.com/questions/3704372/…
    • 它表示引用,但首先解析符号:'+ 仅表示 '+',而 `+ 表示 'clojure.core/+',但如果你说 (def + rest),那么 ` + 变成 'user/+' - 所以这就是符号在环境中解析的内容
    • Markdown 问题:此答案中至少有一个未转义的反引号导致麻烦。
    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多