12

I am trying to get meta-data of all built-in Clojure functions.

In previous question I've learned that this can be achieved using something like ^#'func_name (get the var object's meta data). But I didn't manage to do it programmatically, where func-name is not known in advance.

For example trying to get the metadata of the last function in clojure.core:

user=> (use 'clojure.contrib.ns-utils)
nil
user=> (def last-func (last (vars clojure.core)))

user=> last-func
zipmap

;The real metadata (zipmap is hardcoded)
user=> ^#'zipmap
{:ns #<Namespace clojure.core>, :name zipmap, :file "clojure/core.clj", :line 1661, :arglists ([keys vals]), :doc "Returns a map .."}

;Try to get programmatically, but get shit
user=> ^#'last-func
{:ns #<Namespace user>, :name last-func, :file "NO_SOURCE_PATH", :line 282}

How can it be done? I tried numerous variations already, but nothing does the trick.

2 Answers 2

10

You are a looking for meta and ns-resolve.

user=> (let [fun "map"] (meta (ns-resolve 'clojure.core (symbol fun))))
{:ns #<Namespace clojure.core>, :name map, :file "clojure/core.clj", :line 1705, :arglists ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]), :doc "Returns a lazy sequence consisting of the result of applying f to the\n  set of first i tems of each coll, followed by applying f to the set\n  of second items in each coll, until any one of the colls is\n  exhausted.  Any remaining items in other colls are ignored. Function\n  f should accept number-of-colls arguments."}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! Indeed, ^(ns-resolve 'clojure.core last-func) achieves this
I found another way to do this using the "intern" function: ^(intern 'clojure.core last-func)
This is a dangerous solution: <pre><code>user=> (meta (intern 'clojure.core (with-meta 'count :meta :data}))) {:ns #<Namespace clojure.core>, :name count, :meta :data}</code></pre> So be careful where your symbol comes from. I would still recommend ns-resolve over intern.
3

Technically functions cannot have metadata in Clojure currently:

http://www.assembla.com/spaces/clojure/tickets/94-GC--Issue-90---%09-Support-metadata-on-fns

However, vars which are bound to functions may, and it looks like that's what you're finding with ns-resolve. (meta last-func) would work too. Since last-func is the var itself, ^#'last-func (which is shorthand for (meta (var (quote last-func)))) has a redundant var dereferencing.

2 Comments

No. (meta last-func) doens't work. Try it yourself and see. It returns nil
clojure.contrib.ns-utils/vars returns a list of symbols rather than a list of vars, that's why it doesn't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.