On Mar 8, 9:14 pm, Andreas Kostler <andreas.koestler.le...@gmail.com>
wrote:
> Hi Daniel,
> Thanks for your reply.
> On 09/03/2011, at 11:57 AM, Daniel Solano Gomez wrote:
> > On Wed Mar  9 11:16 2011, Andreas Kostler wrote:
> >> Hi all,
>
> >> I need a macro to basically outputs this:
>
> >> (macroexpand '(chain-field-queries record "location" "name" "country"))
> >> (. (. (. record (field "location")) (field "name")) (field "country"))
>
> >> Which chains method calls on a java object. e.g. 
> >> record.field("location").field("name").field("country"). etc...
> >> so far so good. I though I could modify the .. macro for this:
>
> >> (defmacro chain-field-queries
> >>          ([x form]  `(. ~x (field ~form)))
> >>        ([x form & more] `(chain (. ~x (field ~form)) ~@more)))
>
> >> However, this results in
> >> (macroexpand '(chain-field-queries record "location" "name" "country"))
> >> (. (. (. record (user/field "location")) (user/field "name")) (user/field 
> >> "country"))
>
> > You could quote the field as a symbol:
>
> > (defmacro chain-field-queries
> >  ([x form] `(. ~x (~'field ~form)))
> >  ([x form & more] `(chain-field-queries (. ~x (~'field ~form)) ~@more)))
>
> Yes, I don't know why I wasn't thinking of doing that...
>
> > Is a macro really required?  You can do this as a function:
>
> I think it is required. I'm trying to compose a query of the form
>
> (defn make-native-query [db str foo]
>             (. (proxy [ONativeSynchQuery]
>                    [db str foo]
>                    (filter [rec]
>                         (.. rec (field "location") (eq "Madrid") go))) run 
> objs))
>
> Unfortunately, I'm bound to this style of query composition by the java api 
> I'm working with. So ideally, I'd like to be able to do something like
>
> (select (where [[location eq "Madrid"]
>                                 and [name eq "Dhali"]])
>
> And this would expand to
>
> (defn make-native-query [db str foo]
>             (. (proxy [ONativeSynchQuery]
>                    [db str foo]
>                    (filter [rec]
>                         (.. rec (field "location") (eq "Madrid") and (field 
> "name") (eq "Dhali") go))) run objs))
>
> So, technically, I want something along the lines
>
> (defn make-native-query [db str foo]
>             (. (proxy [ONativeSynchQuery]
>                    [db str foo]
>                    (filter [rec]
>                         (.. rec (create-query [[location eq "Madrid"]
>                                                                 and
>                                                                 [name eq 
> "Dhali"]]) go))) run objs))
>
> However, this doesn't seem to be possible. dot-dot doesn't evaluate the 
> create-query macro.
> I must be missing something. If anyone could point me in the right direction 
> :)
>
> Andreas
>
>
>
>
>
>
>
> > (defn chain-field-queries
> >  [record & fields]
> >  (let [query (fn [r f] (. r (field f)))]
> >    (reduce query record fields)))
>
> > Sincerely,
>
> > Daniel Solano Gómez

You seem to be missing Daniel's point. There's no reason you need to
expand into exactly (.. foo (field "test") (field "more")); you could
just as well expand into (let [data1 foo, data2 (.field data1 "test"),
data3 (.field data2 "more")] data3), which is basically what the ..
shorthand expands to eventually.

And because the latter result is exactly the sort of thing reduce is
good at, you don't need a macro at all.

-- 
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

Reply via email to