The Publics Good
tl;dr ns-publics gives you a list of the the public vars in a Clojure namespace.
When I was writing up my quick note on mapv,
I wanted to flesh it out by looking for similar functions in clojure.core.
I’ve never really needed to introspect a Clojure namespace like that before,
so I started with a web search.
That turned up the ns-publics function,
which,
as it says on the tin,
returns all the public vars in the given namespace.
Specifically,
it returns a map whose keys are symbols,
and whose values are the interned vars.1
user=> (in-ns 'foo)
#object[clojure.lang.Namespace 0x66b72664 "foo"]
foo=> (clojure.core/ns-publics 'foo)
{}
foo=> (def bar "BAR!")
#'foo/bar
foo=> (def ^:private baz "BAZ!")
#'foo/baz
foo=> (clojure.core/ns-publics 'foo)
{bar #'foo/bar}
Groovy.
So for my use case
(finding mapv and its relatives)
all I have to do is this:
(->> (ns-publics 'clojure.core)
keys
(filter #(clojure.string/ends-with? % "v")))
(filterv reduce-kv mapv)
Since reduce-kv is something else entirely,
it looks like mapv and filterv are the vector-producing siblings.
(As reported in that earlier post. 😀)
And speaking of related functions,
ns-publics has its share of kin:
-
ns-internsis a map of all the vars, whether public or private. (A superset ofns-publics.) -
ns-aliasesis a map of all the aliased namespaces in a namespace. That is,(require '[clojure.string :as str])would causens-aliasesto produce a map including{str #object[clojure.lang.Namespace 0x35c09b94 "clojure.string"]}. -
ns-refersis a map of all the function references in a namespace. That is,(require '[clojure.string :refer [ends-with?]])would causens-referswould produce a map including{ends-with? #'clojure.string/ends-with?}. -
ns-importsis a map of all the Java imports in a namespace. That is,(import '[java.util Base64])would causens-importsto produce a map including{Base64 java.util.Base64}. -
ns-mapis a big ol’ map that’s essentially(merge (ns-interns *ns*) (ns-imports *ns) (ns-refers *ns*)). (So it doesn’t includens-aliases.)
It’s nifty, though not surprising, that Clojure has mechanisms for getting at this information. It’s always fun to get a chance to explore another corner of the language.
Questions? Comments? Contact me!
Tools Used
- Clojure
- 1.10.1