3

I'm working on a thin wrapper around a js library and I want to dynamically generate variables from a list for use in other namespaces.

e.g. Given a list of (:foo :bar :baz), I want to dynamically generate:

(def foo (some-fn foo))
(def bar (some-fn bar))
(def baz (some-fn baz))

I found some solutions for Clojure using interns, but that differs in implementation in CLJS. Alternatively, I can generate and print the necessary expressions and evaluate it each time but I'm hoping for a more programmatic solution.

  • 2
    Welcome! You can definitely achieve that with a macro - code that generates code. I'd recommend going over Clojure for the Brave and True's chapter on macros: https://www.braveclojure.com/writing-macros/. For macros on CLJS this is a good resource https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html – Aisamu Dec 16 '19 at 14:03
  • Very helpful links thank you, I learned a lot! Where I struggle is passing in values correctly. It works if I define a macro `(defmacro blah [k v] \`(def ~(symbol (str k)) (partial ~v)))` and call `(blah "test-symbol" identity)` from another ns. However, I have a predefined list I'm trying to iterate over that looks like `[["a" (fn [x] ..)] ["b" (fn [y] ..)]]` and I'm trying to iterate over it as such: `(doseq [[k v] predefined-list] (blah k v))`. The issue is the k and v don't evaluate to the actual values in the macro. I'm not sure if it's because I'm doing it from a different ns or what. – Ahmed Almutawa Dec 17 '19 at 17:14
  • It might be useful to write a function that spits out the code you'd expect to see, and to use that function from your macro. It's easier to see binding issues that way! (And yes, IIRC you can't `def` across namespaces) – Aisamu Jan 06 '20 at 17:27

0 Answers0