1

If I have a namespace symbol e.g. 'clojure.core or a path to a clojure source file how can I get all symbols that are new to the namespace, i.e. not :refer-ed or interned in another namespace?

Those symbols would come from top level defs (and defns) but also inside let bindings and such. My goal is to analyze a namespace and walk the tree effectively doing a find-replace on certain symbols based on a predicate.

Edit: I'm not just looking for top level vars, I'm looking for any symbol. If there's a function with a let binding in it I'm looking for symbol that was bound.

Cody Canning
  • 176
  • 3
  • 14
  • You will probably want to use clojure.tools.analyzer rather than walking the tree yourself. It should be able to tell you where symbols come from as part of the tree walk anyway, so you won't need this preliminary step of gathering "new" symbols anyway. – amalloy Oct 15 '17 at 18:49
  • Possible duplicate of [How to list the functions of a namespace?](https://stackoverflow.com/questions/2747294/how-to-list-the-functions-of-a-namespace) – Mars Oct 16 '17 at 01:59
  • See https://stackoverflow.com/a/19664649/1455243 . Your question not exactly the same as [how to list functions of a namespace](https://stackoverflow.com/questions/2747294/how-to-list-the-functions-of-a-namespace/19664649#19664649) but `dir` in that answer does what you want, it appears. – Mars Oct 16 '17 at 02:00
  • Not quite, dir won't get me the non-interned symbols in var scope like those in a let binding – Cody Canning Oct 16 '17 at 02:43

1 Answers1

3

The comments you've received tell you how to get the top-level refs, however there's only one way to get the local let bindings, and that's to access the &env special form which is only available inside a macro:

(defmacro info []
  (println &env))

(def a 5)
(let [b a] (let [c 8] (info)))

;{ b #object[clojure.lang.Compiler$LocalBinding 0x72458346 clojure.lang.Compiler$LocalBinding@72458346],
;  c #object[clojure.lang.Compiler$LocalBinding 0x5f437195 clojure.lang.Compiler$LocalBinding@5f437195]}

To get a map of local names to local values, for example:

(defmacro inspect []
  (->> (keys &env)
       (map (fn [k] [`'~k k]))
       (into {})))

(let [b a] (let [c 8] (inspect)))
; => {b 5, c 8}
tarmes
  • 15,366
  • 10
  • 53
  • 87