3
votes

Context

I am using Clojurescript and I am trying to define a lot of functions at compile time to wrap a Javascript API. My code works fine with lower level of optimization of the compiler. Yes, when I use the :optimizations :advanced Clojurescript compiler flag, the compiler throws warning: Use of undeclared Var my.namespace/fname and my code does not work at runtime (some mangled symbol not found).

Here is a minimum example of the issue:

(defmacro create-a-function [l]
  `(defn ~l [o#] (inc o#)))

(create-a-function fname)

;; Below inside another function
(defn fname-clone [k]
  (fname k))

I decide a function called fname at compile-time using the macro create-a-function. When I try to call the function at runtime it fails.

What have I tried?

  • Lower optimization level: it works
  • Tested that the macro works fine at the repl
  • Using declare, like (declare fname), which gets rid of the warning at compile time but fails at runtime with the same error.

My question

How can I make this kind of code work with advanced level of optimization?

1
I am not able to reproduce your problem. I copy pasted your code and it works correctly here under advanced optimization. I assume you did put the macro in a separate clj or cljc file and import using require-macros? Also, what version of clojurescript are you running? I am on clojurescript 1.10.238 with shadow-cljs. I don't think shadow-cljs makes a difference here though.. - Hendrik Poernama

1 Answers

3
votes

I reproduced your code in this repo and it works.

Note that you have to put your macro in a .clj file.

When you want to use macros from a .cljc file in ClojureScript, use macrovich.