Fork me on GitHub
#clojurescript
<
2024-01-18
>
Janet A. Carr20:01:19

hey all, I'm trying to create a macro to use in the Clojurescript side of my cljc library. Basically, it's a complete rip-off of cljs.core/simple-benchmark but uses (js/performance.now) instead of (.getTime (js/Date.)). For some reason I can't get it to compile though. if I have the :cljs reader conditional, I get "benchmark does not exist" if I ditch the conditional I get things like "var bindings does not exist". And that does mean it exists in a cljc file of it's own.

#?(:cljs
   (cljs.core/defmacro benchmark
     [bindings expr iterations & {:keys [print-fn] :or {print-fn 'println}}]
     (cljs.core/let [bs-str   (pr-str bindings)
                     expr-str (pr-str expr)]
       `(let ~bindings
          (let [start#   (js/performance.now)
                ret#     (dotimes [_# ~iterations] ~expr)
                end#     (js/performance.now)
                elapsed# (- end# start#)]
            (~print-fn (cljs.core/str ~bs-str ", " ~expr-str ", "
                                      ~iterations " runs, " elapsed# " msecs")))))))

thheller20:01:03

I'd suggest moving the only platform dependent part into a helper function. so the macro just calls (get-timestamp) or whatever and nothing host specific. then the macro becomes much easier and the rest you can solve via reader conditionals

Janet A. Carr20:01:47

That's funny I was just reading your blog post on the subject lol

thheller20:01:41

yeah cljc is a bit of a mind bender, so avoid as much of it as you can

Janet A. Carr20:01:15

Do you know if I need to qualify the symbols defmacro, let, and str like that ?

thheller20:01:16

core symbols no

Janet A. Carr20:01:18

ah, seems to be working now. thank you very much 🙂

👍 1