The ability to use macros to do code generation and transformation is extremely useful. However, you still have to explicitly "call" the macro everywhere you want it to be used. In many scenarios, it might be desirable to do code transformation/generation on code, without explicitly modifying that code to call the macro.
This could be accomplished by declaring a "meta-macro", which combines a normal macro with a function which takes a form and tests whether the macro ought to be applied. Then, somewhere in the compilation pipeline, every form is passed to the test function, and the macro applied if it returns true. Sort of like aspect-oriented programming in Java. For example, say I have a codebase that makes frequent calls to a (sql ...) function to make a query to the database. I'm tracking down an obscure performance bug, and I decide I want to log all calls to (sql...), and time how long they took. But I don't want to modify the sql function itself (it's in a third-party library), and it'd be a major pain to find and replace all the hundreds of calls to it in my codebase with a normal macro call, particularly as I'm going to want to remove it all again after I finish my analysis. Enter metamacros: (defmacro my-logger [sqlform] (do...)) ;standard macro body, wrapping a form with timing and logging code. (def-meta-macro log-sql (fn [form] (if (= sql (first form)))) ; test function my-logger) ; macro to apply Recompile, and, poof. I've instrumented my entire program with additional functionality in a handful of lines, without impact to my existing codebase. Of course, this would be tremendously susceptible to abuse, and if used inappropriately could lead to some very, very hard-to-debug errors. I'd think long and hard before using it in production code at all (maybe even enable metamacros only with a specific compiler flag, turned off by default?) But it's also very powerful, and allows one to try new things across a codebase very easily. It's also incredibly powerful... you could run it over a whole codebase to do static analysis and transformations to improve performance, or to catch stylistic errors. Hell, in theory, you could implement the entire compiler just in metamacros ;) Any thoughts? I grant you, the potential for abuse is huge. Would the benefits outweigh it? Thanks, -Luke V. -- 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