Search code examples
clojurescript

ClojureScript - Failing to iterate over the ns-unmap function


I'm having trouble getting something to work in ClojureScript that works in Clojure no problem.

(defn unmap [nspace & vars]
  (doseq [var vars] (ns-unmap nspace var)))

Usage as:

(unmap 'some.nspace 'vars 'to 'be 'removed)

You can also make unmap a macro so you don't have to quote everything. All it does is iterate over a list of symbols and pluck their bindings from a given namespace.

Neither the macro form, or the unmap function work in ClojureScript (they work fine in Clojure). I get the following error when trying to define the above function.

Unexpected error (AssertionError) macroexpanding cljs.core/ns-unmap. Assert failed: Arguments to ns-unmap must be quoted symbols

Not sure if this is a bug. It seems like ClojureScript is looking for a type hint. If anyone knows how to get this to work it would be appreciated.


Solution

  • In ClojureScript, the ns-unmap macro is designed to be used at the REPL to manipulate both runtime and compiler state used in the implementation of namespaces at dev time.

    The symbols passed to ns-unmap need to be known at compile time in order for it to properly manipulate compiler state at macroexpansion time.

    This problem can be solved by defining a macro which expands to a do containing each of the desired ns-unmap invocations.

    Here is an example:

    (defmacro unmap [nspace & vars]
     `(do
       ~@(map (fn [var] 
               `(ns-unmap ~nspace ~var)) 
          vars)))