On Jun 8, 2009, at 3:50 PM, Meikel Brandmeyer wrote:

> And now you can track the event passing. Eh.. well..
> Not quite! First you have to recompile all your code
> and restart the application. Since a macro gets
> expanded at compile time, there is no way to change
> the expansion afterwards.

Another problem is that you cannot use macros or special forms with  
higher-order functions. If your macro looks a lot like a function, you  
or someone you love may be tempted to use it from a higher-order  
function. This will end in tears:

user> (defmacro square-m [x] `(* ~x ~x))
#'user/square-m
user> (square-m 5)
25
user> (macroexpand '(square-m 5))
(clojure.core/* 5 5)

user> (defn square-f [x] (* x x))
#'user/square-f
user> (apply square-f '(3))
9

user> (apply square-m '(3))
Can't take value of a macro: #'user/square-m
   [Thrown class java.lang.Exception]

user> (map square-f (range 5))
(0 1 4 9 16)

user> (map square-m (range 5))
Can't take value of a macro: #'user/square-m
   [Thrown class java.lang.Exception]

IMO, macros are a wonderful device for introducing syntactic sugar.  
Seibel's define-binary-class in PCL is a good example of a substantial  
improvement:

http://gigamonkeys.com/book/practical-parsing-binary-files.html

Unless it's a visual, syntactic benefit which will eliminate  
substantial boilerplate, I wouldn't go near a macro. Across all my  
Common Lisp code I have 1 macro for about every 32 functions. I  
suspect this value is not representative of actual practice because my  
Lisp was exploratory and short. Clojure's own source code has 65  
macros to 464 functions, or about 1 to 8 (according to "grep -ir defn  
* | wc -l" vs. "grep -ir defmacro * | wc -l"). Just another something  
to keep in mind when considering using a macro: they should be  
uncommon or rare compared to functions.

> So to summarise:
>
> - write the code which you want in your macro
> - write a macro which expands into the code with
>  variable parts as macro arguments.
> - extract the parts which are not required to be
>  a macro as a function
> - modify the macro to simply call the function

I think this is extremely good advice.

Thanks!

—
Daniel Lyons
http://www.storytotell.org -- Tell It!


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