Macros 防止在if表达式的假分支中进行宏扩展

Macros 防止在if表达式的假分支中进行宏扩展,macros,clojure,expansion,Macros,Clojure,Expansion,在Clojure中,不计算与条件不匹配的if表达式的分支,因此在计算以下表达式时不会引发异常: => (if nil (/ 1 0)) nil 但是,在计算if之前,宏仍将展开,因此您仍然可以得到如下异常: => (if nil (proxy [nil] [])) CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1) 我正在编写一个宏,其中接口的名称有时会作为arg提供,在这种

在Clojure中,不计算与条件不匹配的
if
表达式的分支,因此在计算以下表达式时不会引发异常:

=> (if nil (/ 1 0))
nil
但是,在计算
if
之前,宏仍将展开,因此您仍然可以得到如下异常:

=> (if nil (proxy [nil] []))
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1)
我正在编写一个宏,其中接口的名称有时会作为arg提供,在这种情况下,宏将生成调用
proxy
的代码。其他时候,接口arg将是
nil
,然后宏将扩展为类似
(如果为nil(代理[nil][])
,因此我得到上述异常。SSCE将是:

=> (defmacro make-listener [listener-name & methods]
     `(if ~listener-name
        (proxy [~listener-name] []
          ~@(map (fn [m] `(~m [e#])) methods))))
#'user/make-listener
=> (make-listener java.awt.event.ActionListener actionPerformed)
#<Object$ActionListener$46793e3a user.proxy$java.lang.Object$ActionListener$46793e3a@ed5b2>
=> (make-listener nil)
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1) 
=>(defmacro生成监听器[监听器名称和方法]
`(如果~侦听器名称
(代理[~侦听器名称][]
~@(map(fn[m]`(~m[e#]))方法)
#'用户/生成侦听器
=>(使侦听器java.awt.event.ActionListener actionPerformed)
#
=>(使侦听器为零)
CompilerException java.lang.NullPointerException,编译:(无源路径:1)

在没有提供接口参数的情况下,如何以不引发异常的方式编写宏?

如果侦听器名称为nil,则宏不应执行任何操作,即您需要在宏展开时检查侦听器名称(不在宏发出的代码中)


如果侦听器名称为nil,则宏不应执行任何操作,即需要在宏展开时检查侦听器名称(不在宏发出的代码中)


Ankur,我不明白为什么你的有效,但sauce的无效。sauce示例中的'if'子句不应该像你的一样延迟代理的创建吗?@jk:
proxy
是一个宏,它在编译器对其进行宏扩展时抛出null异常。null异常是编译时异常而不是运行时异常在.Ankur上,我不明白为什么你的有效,但sauce的无效。sauce示例中的'if'子句不应该像你的一样延迟代理的创建吗?@jk:
proxy
是一个宏,它在编译器对其进行宏扩展时抛出null异常。null异常是编译时异常,而不是运行时异常自慰。
(defmacro make-listener [listener-name & methods]
  (if listener-name
     `(proxy [~listener-name] []
       ~@(map (fn [m] `(~m [e#])) methods))))