"how can i make functions available to clojurescript's eval?" Code Answer


There are two parts to the answer, assuming x is a var associated with a ClojureScript function:

  1. The compiler analysis metadata for x needs to be present in the state passed as the first argument to cljs.js/eval. This is so that, during compilation, things like the arity of x is known, for example.
  2. The JavaScript implementation of the function associated with x needs to be present in the JavaScript runtime. (This is especially true if the function is actually called during the cljs.js/eval call, and not just referenced.)

If x is a core function (say the var #'cljs.core/map for example), then both of these conditions is automatically satisfied. In particular, the metadata will be produced when cljs.js/empty-state is called (assuming :dump-core is true), and the implementation of the core functions will have already been loaded into the JavaScript runtime.

But, let's say x is a wholly new function that you wish to have compiled in the self-hosted environment. The “trick” is to set up and reuse compiler state: For example put the result of (cljs.js.empty-state) into a var, and pass it to every cljs.js/eval call. If you do that, and one of the cljs.js/eval calls involves compiling a defn for x, then the compiler state will be modified (it is actually an atom), with the result being that the compiler metadata for x will be put in the state, along with, of course, the JavaScript implementation for x being set within the JavaScript environment (by virtue of evaluating the JavaScript produced for the defn).

If, on the other hand, x is a function that is part of your “ambient” ClojureScript environment (say, pre-compiled via the JVM ClojureScript compiler, but nevertheless available in the JavaScript runtime), then it will be up to you to somehow to arrange to get the compiler analysis metadata for x into the state passed to cljs.js/eval. If you look at the output of the JVM-based compiler, you will see <ns-name>.cache.json files containing such metadata. Take a look at the data that is in these files and you can ascertain its structure; with that you can see how to swap the needed information into the compiler state under [:cljs.analyzer/namespaces <ns-name>]. The cljs.js/load-analysis-cache! function exists as a helper for this use case, and a self-contained example is at https://stack.com/a/51575204/4284484

By Bundyo on August 18 2022

Answers related to “how can i make functions available to clojurescript's eval?”

Only authorized users can answer the Search term. Please sign in first, or register a free account.