I'm still learning clojure and wrote this decidedly unfunctional bit of 
code as part of a common lisp style DESCRIBE function.

I was wondering what experienced clojure-ers  (what's the proper 
reference?) might suggest to make this function less ugly.

I realize making a purely functional version of this is probably the 
clojure thing to do, but it wasn't worth my time,
nor did I think it would make the code shorter (correct me if I'm wrong).

Anyway, with regard to mutable state is there a more concise and/or 
preferred way to do this?

The function in question is just querying the many maps of a namespace to 
yield another map with some interpretations of the namespace with respect 
to a given symbol.  I am struggling with some of the capabilities of 
namespaces and so this was just a bit of learning code for me, though I 
have to say my resulting DESCRIBE function has been really useful to me. 
 At some point when it's not a total embarrassment perhaps I'll post it.

Thanks for your suggestions:

(defn ns-symbol-relationship
  "Return a map of entries that describe the relationship of a symbol to a 
given namespace."
  [ns symbol]
  (if (not (symbol? symbol))
    (throw (Exception. (str "ns-symbol-relationship expected symbol, got " 
symbol))))
  ;; ns-name ns-aliases ns-imports ns-interns ns-map ns-publics ns-refers
  (with-local-vars [result (transient {})]
    (when (= (ns-name ns) symbol)        ;ns-name gives a symbol
      (var-set result (assoc! (var-get result) :names-ns ns))) ;symbol 
names namespace
    ; ns-aliases gives a map, but the k/v types/semantics are presently 
unknown
    (doseq [[k v] (seq (ns-aliases ns))]
      (when (= k symbol)
        (var-set result (assoc! (var-get result) :alias-for v)))
      (when (= v symbol)
        (var-set result (assoc! (var-get result) :aliased-by k))))
    ;; ns-imports keyed by symbol, valued by class
    (if-let [v (get (ns-imports ns) symbol)]
      (var-set result (assoc! (var-get result) :imports v)))       ;symbol 
names imported class
    ;; ns-interns gives a map, keys are symbols in the namespace, values 
are vars( and special forms?)
    ;; that they map to. 
    (if-let [v (get (ns-interns ns) symbol)]
      (var-set result (assoc! (var-get result) :interns v)))
    ;; ns-maps gives a map, value types/semantics are unknown
    (if-let [v (get (ns-map ns) symbol)]
      (var-set result (assoc! (var-get result) :maps-to v)))
    ;; ns-publics gives a map of public intern mappings, presumably a 
subset of ns-interns
    (if-let [v (get (ns-publics ns) symbol)]
      (var-set result (assoc! (var-get result) :interns-publicly v)))
    ;; ns-refers gives a map of refer-mappings, value semantics unknown
    (if-let [v (get (ns-refers ns) symbol)]
      (var-set result (assoc! (var-get result) :refers-to v)))
    (persistent! (var-get result))))

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to