Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

checking symbol equality in defmacro (clojure)

This returns false.

(defmacro scratch [pattern]
  `(= 'b (first ~pattern)))

(scratch '(b))

However, the output of the following is b.

(defmacro scratch2 [pattern]
  `(first ~pattern))

(scratch2 '(b))

How do I setup the first macro to return true?

like image 216
Michael Dawson Avatar asked Feb 05 '26 12:02

Michael Dawson


1 Answers

that is happening, because the 'b that you introduce in macro is namespaced:

example:

user> (defmacro nsmac []
        `(namespace 'b))

user> (nsmac)
;;=> "user"

while the value you pass isn't:

user> (namespace (first '(b)))
;;=> nil

so, you can pass the namespaced symbol to a macro, like this:

user> (scratch '(user/b)) 
;;=> true

or you can fix you macro to use unnamespaced symbol (known trick with qoute-unquote):

(defmacro scratch [pattern]
  `(= '~'b (first ~pattern)))

user> (scratch '(b)) 
;;=> true

but what you really want, is to check this one in compile-time, because this macro you have is better as a plain function, since it doesn't employ any macro-related goodness.

It could look like this:

(defmacro scratch [pattern]
  (= 'b (first pattern)))

(scratch (b))
;;=> true

something about namespacing can be found in this article

like image 151
leetwinski Avatar answered Feb 09 '26 06:02

leetwinski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!