On Jun 13, 6:38 am, Wrexsoul <d2387...@bsnow.net> wrote: > 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)))))
I think something like this is in clojure-contrib as well. It's a semi- official add-on library for Clojure (You need a CA to contribute), so you should take a look at it :) Also, try using (find-doc "foo") and (doc foo) in a repl for documentation searches. For this function, you might want to check out if-let. I have no idea how the docs on the website are generated. I don't like them much either, and they seem to fall off sync occasionally. :/ > (defmacro with-stack-trace [& body] > `(try (eval (quote (do ~...@body))) > (catch Throwable ex# > (. (get-ultimate-cause ex#) printStackTrace)))) The golden rule: eval is almost always wrong. Why not simply `(try ~...@body (catch ...))? > 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))))) Something like this is in contrib too, done with multimethods. Check out clojure.contrib.generic.functor maps also are sequenceable into a seq of [k v] pairs so instead of explicitly looping it's possible to do (into {} (map (fn [[k v]] [(if keys? (f k) k) (f v)]) coll); notice the destructuring in the lambda parameters and that it returns a vector. I don't see why you do (apply f [k])... That's equivalent to (f k) You could also use destructuring in the let form above: (let [[[k v] & the-rest] s] ...) I also personally dislike functions that take a boolean parameter; if you must, at least make it optional, with default to false and then require users to pass in a keyword (keywords are "true" in a boolean context) like so: (map-preserve-raw inc {1 2, 3 4} :transform-keys-too) > > (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: I didn't quite get your super-lazy-seq, but then again I didn't look at it in detail yet. It seems like it might make constructing lazy seqs easier, but I'd need more examples. The use of atoms feels dubious. It seems to me that you're emulating mutability with them. I might be wrong, but if there's any way to get rid of the atoms, it's worth the effort :) Not to mention file-seq already exists in core, implemented using tree- seq which is rather simple, so your example isn't very convincing. :/ > (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 -~----------~----~----~----~------~----~------~--~---