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