In Clojure, the branch of an if
expression that doesn't match the condition is not evaluated, so no exception is thrown in evaluating the below expression:
=> (if nil (/ 1 0))
nil
However, macros will still be expanded before evaluating the if
, so you can still get exceptions like so:
=> (if nil (proxy [nil] []))
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1)
I'm writing a macro for which the name of an interface will sometimes be provided as an arg, in which case the macro will generate the code for a call to proxy
. Other times, the interface arg will be nil
, and then the macro expands to something like (if nil (proxy [nil] [])
, so I get the above exception. An SSCE would be:
=> (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)
How can I write the macro in a way that doesn't throw an exception when no interface arg is provided?