I've been thinking a lot about macros ever since I asked my question here last year. I think I understand them a lot better now, and part of my brain recognizes them as a really elegant idea - but I'm still having trouble coming up with situations in which I'd want to use them.
I should probably explain where I'm coming from. I'm a Smalltalk/Ruby guy, and I'm trying to imagine what Ruby-with-macros would look like. And I can do that - I can imagine a language that looks like Ruby, has Ruby's object system, and has Lisp-like macros underneath - but I'm having trouble coming up with examples where macros are really a big win. In a few cases, macros seem like they might streamline a bit of syntax (usually by allowing me to write a "naked" Symbol), but... I dunno. It seems like macros ought to be useful for more than that.
After thinking about them a bit, none of the examples on this page are particularly compelling - they all seem to me like workarounds for the ugliness of typing "lambda". But Smalltalk and Ruby both have a much more lightweight syntax for closures. I can write an equivalent to your with-scarce-resource macro using just functions and closures:
def with_scarce_resource(&body) { resource = allocator_for_my_scarce_resource() try { body.call(resource) } finally { deallocate_my_scarce_resource(resource) } }
(That's not valid Ruby code; it's just the syntax that I'm imagining for this new language. Imagine that the try__finally function is the equivalent of your unwind-protect - it's a function that takes two closures, starts executing the first, and executes the second when the first stops for whatever reason.)
So now I can write:
with-scarce-resource { |r| foo() bar() etc() }
Point is, I didn't need macros to do what you did in the Lisp version, and you didn't need them either - you could have done everything with normal functions and lambdas, except that "lambda" is ugly to type, so you wrapped it in a macro. And it seems to me that the map-over-active-allocators example above is similar.
So my current theory is that lambdas are so fundamental that they deserve a special lightweight syntax, and that once you have that, you don't need macros so much anymore. But there must be other things that you use macros for. What are they?
-- AdamSpitz