Here's a bit more, public domain as usual:

(defn get-ultimate-cause [exception]
  (loop [e exception]
    (let [e2 (. e getCause)]
      (if-not e2
        e
        (recur e2)))))

(defmacro with-stack-trace [& body]
  `(try (eval (quote (do ~...@body)))
     (catch Throwable ex#
       (. (get-ultimate-cause ex#) printStackTrace))))

Improved with-stack-trace. I got an exception with causes stacked four
deep, which printed at the repl with the final one ending "... 7 more"
and the line number in my own code that set it off buried in the
elided portion, so I decided to hell with those really deeply nested
exceptions Clojure tends to churn out. The get-ultimate-cause fn gets
the exception at the root of the cause chain, and with-stack-trace now
uses it.

(defn map-preserve-raw [f coll keys?]
  (if (map? coll)
    (loop [m {} s coll]
      (if (empty? s)
        m
        (let [e (first s) k (first e) v (second e)]
          (recur (assoc m (if keys? (apply f [k]) k) (apply f [v]))
(rest s)))))
    (let [x (map f coll)]
      (if (vector? coll)
        (vec x)
        (if (set? coll)
          (set x)
          x)))))

(defn map-preserve [f coll]
  (map-preserve-raw f coll false))

(defn map-code [f coll]
  (map-preserve-raw f coll true))

user=>(map-preserve #(* 2 %) {:key1 3 :key2 17 :key3 1/2})
{:key3 1, :key2 34, :key1 6}

Now one version map-preserve for transforming data and one map-code
for transforming code for macro purposes.

I should make the latter recursive.

Done.

(defn map-code [f code]
  (if (coll? code)
    (map-preserve-raw #(map-code f %) code true)
    (apply f [code])))

This makes with-derefs (part of super-lazy-seq) simpler:

(defn with-derefs [names code]
  (map-code #(if (and (symbol? %) (contains? names %))
               (list 'deref %)
               %) code))

Tested, works.

This new with-derefs is very clear: map-code if symbol in names deref
it otherwise don't touch it. Abstracting this stuff helps readability,
not just productivity.

In fact ...

(defn map-recursive-raw [f obj keys?]
  (if (coll? obj)
    (map-preserve-raw #(map-recursive-raw f % keys?) obj keys?)
    (apply f [obj])))

(defn map-recursive [f coll]
  (map-recursive-raw f coll false))

(defn map-code [f code]
  (map-recursive-raw f code true))

OK, I'm really done this time. I promise.
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to