I think this is an interesting problem, so here are some additional brainstorms on the issue that may or may not be useful...
One strategy to create a global mutable variable from inside the function would be to use def at macroexpansion time to create a var, and then just refer to it in the expansion, like this: (defmacro expand-to-something-with-mutable-global [] ; At macroexpansion time, create a (private) var containing a volatile. (let [global-name (gensym "cache")] (eval `(def ^:private ~global-name (volatile! nil))) ; Now macro can refer to this var, can use as a cache, etc. `(if-let [cache-contents# (deref ~global-name)] (do-something-with cache-contents#) (reset! ~global-name init-value-for-cache)))) Not sure if this would be any faster than ConcurrentHashMap, but I would guess that it would be if Clojure resolves the location of the var in memory once, at compile-time. A related technique would be for Specter to maintain an ArrayList of volatiles. At macroexpansion time, you add a fresh volatile to the end of the ArrayList, noting the index of its location, and then inside the macro you hardcode a lookup in the ArrayList at the specific index to retrieve the volatile containing the cache for this particular expansion. I would expect this to be faster than looking up in a hash map, although there'd be some additional concurrency/locking details to worry about that I assume ConcurrentHashMap handles for you. Or just use an ArrayList's slot directly as the cache (rather than storing a volatile to add a level of indirection), but then the concurrency logistics would be even more complicated. On Tue, May 31, 2016 at 12:50 PM, Nathan Marz <nathan.m...@gmail.com> wrote: > No, because that global mutable variable would need to be specifiable by > Specter on usage of the library. For example, if you wrote: > > (defn foo [] > (select [:a :b] {:a {:b 1}})) > > `select` has no ability to control anything outside the context of its > form. It certainly can't wrap `foo` to put a volatile field in its closure. > So for the static-field idea, it would expand to something like: > > (defn foo [] > (static-field [pathcache] > (if-not pathcache (set! pathcache ...)) > ... > )) > > > > On Tuesday, May 31, 2016 at 3:15:26 PM UTC-4, puzzler wrote: >> >> In your writeup, you say that there would be further speed benefits if >> you could have a global mutable variable within the context of a function >> (like a static field). >> >> Can't you effectively accomplish that already in Clojure like this?: >> >> (let [mycache (volatile! nil)] >> (defn foo [] >> ...))) >> > -- > 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. > -- 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.