-
-
Save lambdahands/7326241 to your computer and use it in GitHub Desktop.
(ns my-project.core | |
(:require-macros [my-project.macros :refer [style-el]])) | |
(defn create-el [kind] | |
(. js/document (createElement (name kind)))) | |
(let [div (create-el :div)] | |
;; Works as expected | |
(style-el div :width "50%") | |
;; Produces no results | |
(doseq [[x y] {:width "25%" :color "#fff"}] | |
(style-el div x y))) |
(ns my-project.macros) | |
(defn to-attr [attr] | |
(symbol (str ".-" (name attr)))) | |
(defmacro style-el [el kwd value] | |
`(set! (-> ~el .-style ~@(to-attr kwd)) ~value)) |
Ah, that makes sense now. I've tinkered around for a solution for a while, and I still can't seem to come up with anything that's at all idiomatic, let alone compiles into ClojureScript.
Is this just not the job for a macro?
Ended up taking some clues from the domina library. I was pretty set on rolling my own methods for the sake of learning, but attempting to apply any sort of JavaScript mindset while programming ClojureScript is an unproductive and frustrating venture.
I've settled with using Google's Closure API, which takes most of the headache out of the equation. Maybe later on in my experience, I'll find a way to solve this particular problem.
Yes the problem here is that you're trying to have runtime code interact with macro code which really isn't possible. style-el
is probably just best written as a plain function.
The code in macros.clj throws for me. It works if you evaluate rather than splice the call to
to-attr
like this (notice the absence of the @ in front of the call toto-attr
):I loaded the above code into a Clojure REPL. Then I typed the following into the REPL to see the macro expansion of the code that appears as the body of doseq:
(macroexpand-1 '(style-el div x y))
And the result is this:
So the problem is that the macro operates on the code you pass in so when you pass
kwd
toto-attr
, you are actually passing the symbolx
rather than the keywords:color
or:width
.