I want to pass a java method call to a function. So instead of this:


(defn call-method []
  (.getCanonicalName Object))


I have something like this...

(defn indirect-call [f clazz]
  (f clazz))

(defn indirect-call-memfn []
  (indirect-call (memfn ^java.lang.Class getCanonicalName) Object))

(defn indirect-call-anon []
  (indirect-call #(.getCanonicalName ^java.lang.Class %) Object))

I am not sure which is faster yet, but either should work. But,
performance-wise I am creating a new function for every call (the
anonymous function) when I only ever need one. Which isn't idea.

One solution would be this:

(def indirect-call-memfn-cached
  (let [f (memfn ^java.lang.Class getCanonicalName)]
    (fn []
      (indirect-call f Object))))

(def indirect-call-anon-cached
  (let [f #(.getCanonicalName ^java.lang.Class %)]
    (fn []
      (indirect-call f Object))))


Or, if I want to stay using defn the slightly evil looking:

(let [f #(.getCanonicalName ^java.lang.Class %)]
  (defn indirect-call-defn-anon-cached[]
    (indirect-call f Object)))


Which seems to work, but is fairly horrible syntactically.

I have thought about writing a macro which I might call "one-fn" which
looks like fn but caches. The best I have come up with is to turn the
contents of the &form variable into a hash, and store the functions in
global state. So something like this...

(one-fn [x] (.getCanonicalName x))


At run time we would have something like

(if-let [f (get &one-fn-state 423432423)]
  f
  (let [r (fn [x] (.getCanonicalName x))]
      (swap! one-fn-state assoc 423432423 r)
      r))
   

I can see some nasty edge cases where this will break, of course. But
most of all, I wonder whether I am missing something obvious that would
be far better. In the ideal world, I'd like one-fn to affect the
compiled code, so that a single instance is shared, but I can't see a
way to achieve this.

Thoughts? Has it already been done?

Phil

-- 
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/d/optout.

Reply via email to