Skip to content

Instantly share code, notes, and snippets.

@lambdahands
Created November 5, 2013 21:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lambdahands/7326241 to your computer and use it in GitHub Desktop.
Save lambdahands/7326241 to your computer and use it in GitHub Desktop.
Using bound vars as argument to `to-attr` in macro produces no results. Not sure what mistake I'm making.
(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))
@rigdern
Copy link

rigdern commented Nov 6, 2013

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 to to-attr):

(defn to-attr [attr]
  (symbol (str ".-" (name attr))))

(defmacro style-el [el kwd value]
  `(set! (-> ~el .-style ~(to-attr kwd)) ~value))

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:

(set! (clojure.core/-> div .-style .-x) y)

So the problem is that the macro operates on the code you pass in so when you pass kwd to to-attr, you are actually passing the symbol x rather than the keywords :color or :width.

@lambdahands
Copy link
Author

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?

@lambdahands
Copy link
Author

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.

@swannodette
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment