【问题标题】:if 'x evaluates to (var x) in clojure, why aren't they equal?如果 'x 在 clojure 中计算为 (var x),为什么它们不相等?
【发布时间】:2017-01-19 09:27:06
【问题描述】:

在 O'Reilly 《Clojure Programming: Practical Lisp for the Java World》中,有一句话:

var 特殊形式这样做:

(def x 5)
(var x) 
;= #' user/x 

您已经多次看到在 REPL 中如何打印 var:#',后跟一个符号。这是扩展为对 var 的调用的读取器语法:

 #'x 
 ;= #' user/x

(Kindle 位置 1278-1282)。

对此进行测试似乎并非如此。我认为类型类型是相同的。

[user]> (def x 5)
#'user/x

[user]> (= 'x (var x))
false

[user]> (type 'x)
#<Class@c540f5a clojure.lang.Symbol>

[user]> (type (var x))
#<Class@77e9807f clojure.lang.Var>

[user]> 'x
x

[user]> (var x)
#'user/x

【问题讨论】:

  • 'x 计算结果为 (quote x),而不是 (var x)(= 'x (quote x)) 的计算结果为 truex 只是一个符号。它不需要引用 var 或其他任何内容。

标签: clojure


【解决方案1】:

您缺少# 符号:

(def x 5)
(spyx (var x))
(spyx #'x)

(var x) => #'tst.clj.core/x
(var x) => #'tst.clj.core/x

clojure 阅读器使用源文件中的字符,并在到达编译器之前替换 #'x => (var x)。正如您在上面看到的,spyx 宏(“间谍表达式”)甚至看不到原始的 #'x 表达式 - 已经发生了替换。

因此我们得到:

(= #'x (var x)) => true

你也可以试试:

(println "type 1:  " (type (var x)))
(println "type 2:  " (type #'x))

;=> type 1:   clojure.lang.Var
;=> type 2:   clojure.lang.Var

如果您想使用 spyspyxspyxx 宏,您需要将其添加到您的 project.clj

   [tupelo "0.9.19"]

【讨论】:

  • 您可以通过检查简单引用输入的结果来更清楚地演示读取时替换:'[(var x) #'x]
  • 啊,谢谢。你知道,我想我很困惑,并认为# 是一个提示。
猜你喜欢
  • 2018-09-25
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多