Clojure扩展阅读器宏。

3

如何找出阅读器宏的作用?

例如,我知道正则表达式#"abc"(re-pattern "abc")相同。

但是下面的代码:(macroexpand #"abc" )返回结果为#"abc",那么我如何从阅读器特殊形式转换为“普通”函数形式呢?


1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - leetwinski
1
由于所有的读取宏都是硬编码的,而且它们的数量在思想上是有限制的(而且很简单),所以人们只需要记住它们中的所有内容,这样他就不必费心去“找出”它的作用,而是直接知道... - leetwinski
没错,我的问题更多是关于可发现性而不是修改行为。如果你把这个作为答案,我会接受它。 - nha
@leetwinski 我不得不接受Andre的答案,因为它提供了对我一直疑惑的许多情况的解决方法(尽管不是我在问题中选择的示例)。 - nha
1个回答

3

您可以使用read-string查找读取器扩展的内容:

(read-string "`(rest ~f)")
=>
(clojure.core/seq
 (clojure.core/concat (clojure.core/list (quote clojure.core/rest)) (clojure.core/list f)))
(read-string "#(x %&)")
=> (fn* [& rest__92046#] (x rest__92046#))
(read-string "`(~@x)")
=> (clojure.core/seq (clojure.core/concat x))
(read-string "`(~x)")
=> (clojure.core/seq (clojure.core/concat (clojure.core/list x)))
(read-string "'map")
=> (quote map)
(read-string "#'map")
=> (var map)
(read-string "@x")
=> (clojure.core/deref x)
(binding [*print-meta* true]
  (pr-str (read-string "(def ^:foo x 'map)")))
=> "(def ^{:foo true} x (quote map))"
(read-string "#\"x\"")
=> #"x"

然而,在您的情况下:正则表达式以同样的方式打印回来,因为这就是它在Clojure中的打印方式

(class #"abc")
=> java.util.regex.Pattern

但是您可以使用macroexpand完全做到同样的效果:(macroexpand '\(rest ~f)),那么为什么还要费心去使用read-string`呢? - leetwinski
在你的例子中,macroexpand 什么也不做。它是由读取器展开的。 - ClojureMostly
同意。那么,如果显示了引用表达式的展开,为什么还要使用read-string呢? - leetwinski
为了不让在SO上的读者更加困惑,不再添加引号 :) - ClojureMostly
不,你是对的,元数据是通过这种方式被消除了。 - leetwinski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接