A couple points on the metaprogramming space (these aren't about the article, but the article reminded me of them):
1. Macros aren't unique to lisp. They're most developed and used in the lisp family, but you don't need to have a homoiconic language to have macros. The Mirah programming language--statically typed Ruby on the JVM--has non-hygenic macros, I know there's been a number of efforts to add macros to coffeescript (so far without success), and there are a number of academic languages that also have them. None are in widespread use, but they exist.
2. Metaprogramming's power is primarily limited by the restrictions of the host language. The best example I know of is Io where pretty much anything other than commas and parentheses is up for grabs. Example: http://anttih.com/blog/2010/10/29/json-in-io.html
3. User definable mixfix operators are in the sameish domain. Unfortunately, they're almost always mentioned in passing by people who know what they are so I don't have a good reference for introducing what they are and don't have direct experience working with them. I'm just mentioning them as something to be aware of if you're interested in general metaprogramming concepts. Here's the closest thing to an intro I could google up: http://maude.cs.uiuc.edu/maude1/manual/maude-manual-html/mau...
Macros actually saw a great deal of use in the assembly-language space for as long as people were writing large programs directly in assembly. (Typically, the assemblers would let you define "pseudo-operations" which could appear in place of an actual opcode, and whose arguments were used to fill in templates.) In fact, one of the raps on Unix among "big iron" programmers was that its assembler was so primitive --- meaning, in particular, that it had no useful macro facilities.
The question isn't so much whether other languages have something they call "macros", but whether their macro systems approach Lisp's in power, flexibility, ease of use, integration with the language, and natural fit on to the language representation? Or is the macro system in question more of a Turing tarpit?
1. Yet, still to this day, Lisp remains one of the few languages with powerful macros that normal people cannot only use, but enjoy. Also the Scheme/Racket community actively researches how to make them more robust and easier to write (yes equally powerful macro systems do exist for other languages - however, ease of use is often sacrificed)
2. Io is great but the depth of it's runtime meta-programming facilities make it horrifically inefficient.
I don't disagree and I'm not trying to argue with the article or anything. I was just hoping to point people interested in the topic towards things that took me a while to realize/run across.
As for Io's efficiency, I think that's more about the implementation than in the language. Javascript (prototypal inheritance) and Smalltalk (message passing) aren't that far off and both have decent performance. I know Steve Dekorte was working on getting Io running in javascript in December but I don't think it's a high priority project for him.
For (1) look at OCaml's P4 (very integrated) preprocessor for some macros in a non-homoiconic statically typed language.
For (3) look at how Haskell defines new operators. I find Haskell's use of completely new operator-squiggles plus type classes for something faintly similar to C++-style overloading, much more sensible than say, C++-style overloading.
There is also template haskell. Nemerle is another non-homoiconic language with powerful metaprogramming abilities using hygienic macros. It really is quite impressive what those guys are doing. And it is such a contrast (not all inferior IMHO) to the lisp way. A dual approach maybe.
1. Macros aren't unique to lisp. They're most developed and used in the lisp family, but you don't need to have a homoiconic language to have macros. The Mirah programming language--statically typed Ruby on the JVM--has non-hygenic macros, I know there's been a number of efforts to add macros to coffeescript (so far without success), and there are a number of academic languages that also have them. None are in widespread use, but they exist.
2. Metaprogramming's power is primarily limited by the restrictions of the host language. The best example I know of is Io where pretty much anything other than commas and parentheses is up for grabs. Example: http://anttih.com/blog/2010/10/29/json-in-io.html
3. User definable mixfix operators are in the sameish domain. Unfortunately, they're almost always mentioned in passing by people who know what they are so I don't have a good reference for introducing what they are and don't have direct experience working with them. I'm just mentioning them as something to be aware of if you're interested in general metaprogramming concepts. Here's the closest thing to an intro I could google up: http://maude.cs.uiuc.edu/maude1/manual/maude-manual-html/mau...