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-interns
is a map of all the vars, whether public or private. (A superset ofns-publics
.) -
ns-aliases
is a map of all the aliased namespaces in a namespace. That is,(require '[clojure.string :as str])
would causens-aliases
to produce a map including{str #object[clojure.lang.Namespace 0x35c09b94 "clojure.string"]}
. -
ns-refers
is a map of all the function references in a namespace. That is,(require '[clojure.string :refer [ends-with?]])
would causens-refers
would produce a map including{ends-with? #'clojure.string/ends-with?}
. -
ns-imports
is a map of all the Java imports in a namespace. That is,(import '[java.util Base64])
would causens-imports
to produce a map including{Base64 java.util.Base64}
. -
ns-map
is 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