关于clojurescript:如何在clojure中实现主机互操作点宏

How is the host interop dot macro implemented in clojure

我正在学习Clojure,并遇到了用于与主机平台互操作的语法。

1
2
3
4
(.toUpperCase"fred")
->"FRED"
(.getName String)
->"java.lang.String"

我很好奇这是如何实现的。文档说他们在扩展时被扩展为点特殊格式,例如

1
(.instanceMember instance args*) ==> (. instance instanceMember args*)

这里似乎有特殊的行为。通常,宏调用中的第一个参数就是宏符号。但是,在这种情况下,(.是某种通用宏,它会根据调用中紧随(.之后的第一个参数(如(.toUpperCase ...(.getName ...)扩展为不同的内容。

那么这是如何实现的?实现宏是否使用某种特殊的语法(我不知道该语法)来获得该行为,或者该类型的宏实现行为在用户空间中不可用。它使用实际的宏还是读取器宏?


这些在成员Accress下的手册的Java Interop部分中进行了描述。这些特殊形式在宏扩展时进行了扩展。

The instanceField form is preferred for fields and required if both a field and a 0-argument method of the same name exist. They all expand into calls to the dot operator (described below) at macroexpansion time. The expansions are as follows:

1
2
3
4
5
(.instanceMember instance args*)  ==> (. instance instanceMember args*)
(.instanceMember Classname args*) ==> (. (identity Classname) instanceMember args*)
(.-instanceField instance)        ==> (. instance -instanceField)
(Classname/staticMethod args*)    ==> (. Classname staticMethod args*)
Classname/staticField             ==> (. Classname staticField)

克洛瑞尔(Clojure)中有多种形式的玛科啤酒:

  • 正常的种类或只是"宏"。您可以编写这些。
  • 阅读器宏,您可以扩展某些使用带标记文字的内容
  • 这些特殊形式具有宏扩展时间评估。另请参见新特殊表格的扩展

  • 我不能轻易回答Clojure,但是这是ClojureScript的工作原理:Is在编译器中确实是一种特殊情况。在尝试对表单进行"常规"宏扩展后,它会退回到此处的某种逻辑,该逻辑从点开始寻找符号(并且在宏扩展以使用new时,这同样处理符号末尾的点):

    https://github.com/clojure/clojurescript/blob/b38ded99dc0967a48824d55ea644bee86b4eae5b/src/main/clojure/cljs/analyzer.cljc#L3882-L3899