Kingfranz
Kingfranz

Reputation: 314

clojure: how do I pass a namespace as a macro parameter?

I'm experimenting with clojure.spec and I thought I would write a macro to save some tedious typing :-)

I'm trying to do this:

(defmacro nup
    [pns pname punit]
    `(s/def :~pns/name (s/and #(string? %) #(= % ~pname)))
    `(s/def :~pns/unit (s/and #(string? %) #(= % ~punit))))

I've tried several version but I can't make the namespace substitution work. Any ideas? Needless to say, macros aren't my strong side.

Upvotes: 2

Views: 192

Answers (1)

ClojureMostly
ClojureMostly

Reputation: 4713

There you go:

(defmacro nup
  [pns pname punit]
  `(do
    (s/def ~(keyword (str pns) "name") (s/and #(string? %) #(= % ~pname)))
    (s/def ~(keyword (str pns) "unit") (s/and #(string? %) #(= % ~punit)))))

(macroexpand-1
  '(nup ab :foo :bar))

But s/def just registers the keyword in the spec's registry. So you don't need a macro at all. Just use a function, much easier.

Upvotes: 1

Related Questions