Welcome! Please see the About page for a little more info on how this works.

+2 votes
in Syntax and reader by
retagged by

The if-not macro is implemented as:

(defmacro if-not
  "Evaluates test. If logical false, evaluates and returns then expr, 
  otherwise else expr, if supplied, else nil."
  {:added "1.0"}
  ([test then] `(if-not ~test ~then nil))
  ([test then else]
   `(if (not ~test) ~then ~else)))

The first form expands to the second, and the second uses not, so if I simplify by removing docs and the other arity, we effectively get:

(defmacro if-not
  [test then else]
  `(if (if ~test false true) then else))

This seems like more work than just reversing the forms. I had assumed that this would instead be:

(defmacro if-not
  "Evaluates test. If logical false, evaluates and returns then expr, 
  otherwise else expr, if supplied, else nil."
  {:added "1.0"}
  ([test then] `(if-not ~test ~then nil))
  ([test then else]
   `(if ~test ~else ~then)))

I appreciate that it's not a big deal, but is there a reason for using not and not just inverting the forms?

PS. I believe this question may have been asked before, but I’ve been searching ask.clojure and can’t find it.

1 Answer

+1 vote
by
selected by
 
Best answer

Logged as https://clojure.atlassian.net/browse/CLJ-2691

This has definitely come up on Slack before, don't know of a jira/ask for it.

I don't think it's a huge deal, could see it mostly coming up if it blows the inline code size boundary or something like that. Difficult to come up with that case, but maybe it would be amenable to a microbenchmark. If anyone does test it, it's important to check Java 8, 11, 17 - this is exactly the kind of thing the jvm gets better at over time and it could easily be less important on newer jvm.

by
Historical note: the question arose (with no conclusive resolution) in 2015: https://groups.google.com/g/clojure/c/pMMS66-Qo1Y/m/-wnJb80pTLkJ
...