On Jan 17, 2009, at 6:29 PM, Stephen C. Gilardi wrote: > > Hi Dan, > > That's interesting. I've given it some thought and I've come to see > it as a version of resolve that tries harder than the default. > Here's an implementation that makes its capabilities purely a > superset of those of resolve. This version works well even with > definitions that don't come from libs like those in clojure.core: > > (defn resolve* > [sym] > (let [ns (namespace sym) > name (name sym) > ns (if ns (symbol ns) (ns-name *ns*)) > name (symbol name)] > (or (and (find-ns ns) (ns-resolve ns name)) > (do > (require ns) > (ns-resolve ns name))))) > > This version takes a symbol just like resolve does. It doesn't > support passing in a string. I think any string to symbol > transformation is easy one for a caller to make if it needs to. I > had an interim version that supported separating the namespace and > name into two arguments, but that would be more like ns-resolve* and > resolve* is every bit as capable.
Hi Stephen, Yes, you're right, this does make sense as a superset of clojure.core/ resolve -- also resolve* is a name that fits much better. > > > I'm interested in hearing any thoughts you may have on this version > as it relates to the problem you're trying to solve. I like that in > Clojure we now have a canonical way to load in a namespace > definition: require. This idea of yours leverages that. Together > with that, we also have a canonical way for one namespace to declare > and satisfy its dependence on another: (ns (:require...)). Given > those two facilities, I wonder what use case you envision for > require-resolve (or resolve*). Is this intended to be used at the > repl? Does it offer a compelling advantage for some kind of work > over calling require directly and then letting the default symbol > resolution mechanism do the work? I like how you phrase that. Yes, you're correct, for dependencies you can identify at coding time (ns (:require ..)) works just fine, but for runtime-introduced dependencies a (require ...) is necessary. My first use case is a "settings file". The settings file (clojure code itself) defines a bunch of settings (duh) which include middleware functions, "template loader" functions (and more to come for sure). So without resolve* there are two options: 1) Import all of the functions to which I need to refer and then identify them directly. 2) Give a two-tuple with namespace and var symbols, which can then be (require ..) and (ns-resolve ..)'d later on. So basically option #1 sucks and #2 is just a more verbose version of using resolve*. My second use case is an url-dispatching system. It's a port (mostly -- java's regex doesn't have named groups and clojure doesn't have keyword arguments) of django's url dispatching system. Basically you define a list of regexes and which function you want to be called when the url matches that regex. So it's the same conundrum as with the settings file, really. Either I can require all of the functions I want to call or give two-tuples of namespace and var -- or use require* > > >> Stephen, if you think this is something suitable for >> clojure.contrib.ns-utils then I'll submit my CA to Rich and you can >> pull it in, otherwise it's here for anyone to use. > > I think it's interesting experimental code. Please do send in a CA > and let's get something like this into ns-utils. > > --Steve > --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---