As Carlo said, we need to keep track of when things are running. Within the 
context of any given unquote, for instance ~@(for [meth meths] ...), we're 
actually executing code. So if you don't quote the 
expression `(~method-name ~args ~@body), you (1) will try to execute the 
function "method-name" right there, giving the *result* to the reify macro 
instead of giving the *expression* to reify.

The REPL is very helpful when digging into why quoting works the way it 
does (and `macroexpand-1` / `macroexpand` in particular for using 
syntax-quoting in macros).

One other idea to look at, besides the great ones Gary mentioned, is a blog 
I did awhile back quoting: 
http://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html

- Colin


On Tuesday, June 18, 2013 2:47:58 AM UTC-5, Hussein B. wrote:
>
> I don't get why we have to use a second 'back tick'. I thought one 
> backtick at the beginning and then we use ~ and ~@ when needed.
>
> On Tuesday, June 18, 2013 2:09:44 AM UTC+2, Carlo wrote:
>>
>> I can't speak to the issues that Gary raised, but I can help you with 
>> your macro.
>>
>> (defmacro servlet [servlet-name & meths]
>>   `(reify Servlet
>>      ~@(for [meth meths]
>>          (let [[method-name args & body] meth
>>                method-name (hyphenated->camel-case method-name)]
>>            `(~method-name ~args ~@body)))))
>>
>> The key here is to keep track of when things are run. The `for` must be 
>> run at compile time in order to generate the code we want, so we have to 
>> escape it with ~@. The code that the `for` creates (in the form of a list) 
>> must then be (quasi-)quoted again by the backtick.
>>
>> Macros certainly take some getting used to.
>>
>>
>> On Tue, Jun 18, 2013 at 8:12 AM, Hussein B. <hubag...@gmail.com> wrote:
>>
>>> Here is my fourth attempt:
>>>
>>> (defmacro servlet [servlet-name & meths]
>>>   `(reify Servlet
>>>      (for [meth ~meths]
>>>        (let [[method-name args & body] ~meth
>>>               camel-case-method-name (hyphenated->camel-case 
>>> ~method-name)]
>>>          (camel-case-method-name ~args ~@body)))))
>>>
>>> Still it is not working :(
>>>
>>> How to fix it?
>>>
>>> On Tuesday, June 18, 2013 12:04:50 AM UTC+2, Gary Trakhman wrote:
>>>
>>>> Unquoting 'camel-case-method-name' is going to try and replace the 
>>>> symbol with it's value during compile-time in the context of the macro 
>>>> itself.
>>>>
>>>> also, reify isn't going to work if you need a named class to actually 
>>>> wire up your servlet, for example with a web.xml. Also, consider that 
>>>> you'll need some AOT compilation for the container to actually see the 
>>>> servlet class.
>>>>
>>>>
>>>> On Mon, Jun 17, 2013 at 4:38 PM, Hussein B. <hubag...@gmail.com> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> My target is to have something like this:
>>>>>
>>>>> (servlet "ArticlesServlet"
>>>>>   (do-get [this request response]
>>>>>     (println "Get Request"))
>>>>>   (do-post [this request response]
>>>>>     (println "Post Request")))
>>>>>
>>>>>
>>>>> I started with this:
>>>>>
>>>>> (defmacro servlet [servlet-name meths]
>>>>>   `(reify Servlet
>>>>>      (for [meth ~@meths]
>>>>>        (let [[method-name params & body] meth
>>>>>               camel-case-method-name (hyphenated->camel-case 
>>>>> method-name)]
>>>>>          (~camel-case-method-name ~@body)))))
>>>>>
>>>>> But of course, it is not working :)
>>>>>
>>>>> I get:
>>>>>
>>>>> CompilerException java.lang.RuntimeException: Unable to resolve 
>>>>> symbol: camel-case-method-name in this context
>>>>>
>>>>> Why?
>>>>>
>>>>> And of course, feel super free to correct my Macro :)
>>>>>
>>>>> Thanks for help and time.
>>>>>
>>>>> -- 
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Clojure" group.
>>>>> To post to this group, send email to clo...@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+u...@**googlegroups.com
>>>>>
>>>>> For more options, visit this group at
>>>>> http://groups.google.com/**group/clojure?hl=en<http://groups.google.com/group/clojure?hl=en>
>>>>> --- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "Clojure" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to clojure+u...@**googlegroups.com.
>>>>>
>>>>> For more options, visit 
>>>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>>>>> .
>>>>>  
>>>>>  
>>>>>
>>>>
>>>>  -- 
>>> -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> --- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>  
>>>  
>>>
>>
>>

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to