On 09/03/2011, at 4:24 PM, Alan wrote:

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

Well, I don't want the symbols location, name, etc to be evaluated...e.g. I 
couldn't use location if not in a macro, right?
Secondly, the structure isn't quite as uniform. Like in the example above 
(.. rec (create-query [[location eq "Madrid"] and [name eq "Dhali"]])) should 
expand to something like

(.. rec (field "location") (eq "Madrid") and (field "name") (eq "Dhali"))

Maybe I'm still missing something but I can't see how I could do that without a 
macro...
Andreas

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

--
"Test-driven Dentistry (TDD!) - Not everything should be test driven"
- Michael Fogus
-- 
**********************************************************
Andreas Koestler, Software Engineer
Leica Geosystems Pty Ltd
270 Gladstone Road, Dutton Park QLD 4102
Main: +61 7 3891 9772     Direct: +61 7 3117 8808
Fax: +61 7 3891 9336
Email: andreas.koest...@leica-geosystems.com

************www.leica-geosystems.com*************

when it has to be right, Leica Geosystems

Please  consider the environment before printing this email.

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