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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---