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