【问题标题】:How is the host interop dot macro implemented in clojureclojure 中主机互操作点宏是如何实现的
【发布时间】:2019-08-14 06:00:22
【问题描述】:

我正在学习 clojure,遇到了这种与主机平台互操作的语法。

(.toUpperCase "fred")
-> "FRED"
(.getName String)
-> "java.lang.String"

我很好奇这是如何实现的。文档说它们在扩展时扩展为点特殊形式,就像这样

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

这里似乎发生了一些特殊的行为。通常,宏调用中的第一个参数只是宏符号。然而,在这种情况下,(. 在某种程度上是一个通用宏,它根据调用中的第一个参数在(. 之后立即扩展为不同的东西,例如(.toUpperCase ...(.getName ...

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

【问题讨论】:

    标签: clojure clojurescript


    【解决方案1】:

    这些在Member Accress 手册的 Java 互操作部分中进行了描述。这些是在宏扩展时扩展的特殊形式。

    instanceField 形式是字段的首选形式,如果同时存在同名的字段和 0 参数方法,则需要。它们都在宏扩展时扩展为对点运算符的调用(如下所述)。扩展如下:

    (.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 中有几种形式的 maco:

    1. 普通类型或只是“宏”。你可以写这些。
    2. reader macros,您可以使用 tagged literals 扩展其中的一些内容
    3. 这些特殊形式带有宏扩展时间评估。另见the expansion for the new special form

    【讨论】:

      【解决方案2】:

      我不能轻易回答 Clojure,但它在 ClojureScript 中是这样工作的:Is 确实在编译器中作为一种特殊情况处理。在表单上尝试“正常”宏扩展后,它会退回到此处查找以点开头的符号的一些逻辑(当宏扩展以使用 new 时,这也类似地处理符号末尾的点):

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-10
        • 1970-01-01
        • 2019-07-18
        • 2015-06-12
        • 2012-08-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多