Share your thoughts in the 2024 State of Clojure Survey!

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

+1 vote
in ClojureScript by

I'm trying to write a cljs macro that transforms clojure data, e.g. {:font-size "14px"} to CSS (font-size: 14px;).

I want the macro to support accepting map literals as well as symbols that resolve to maps.

E.g.

(defstyles foo
  {:font-size "14px"})

;; -- OR --

(def bar {:font-size "14px"})
(defstyles foo bar)

In the macro I've tried something like

(defmacro defstyles [vsym]
  @(resolve vsym))

This seems to work when the var is defined in the same ns that the macro is used, but fails with a NullPointerException when passing a var from another ns.

1 Answer

+2 votes
by
selected by
 
Best answer

No, this is not possible.

The generated code will only be eval'd in some JavaScript runtime (eg. the browser) and only it will "know" the contents of those "vars". From the macro side you can only access the name and some metadata using the cljs.analyzer.api utils but not the actual contents of the var.

Calling resolve will try to resolve the var in CLJ which would only exist if you were using .cljc files. Which may also be the best way to achieve what you are trying to do.

...