Everyone I know who does Lisp says "Learn Lisp and it will change how you look at all other programming languages!" I don't know if that's true or not, but I think I'm starting to learn a bit.
Chapter 8 of Practical Common Lisp discusses macros. As has been pounded into my brain by the author, macros in Lisp aren't like macros in other languages. Nosirree. Nope. Not like them. I definitely won't forget that Lisp macros are different than macros in other languages. And you won't forget that either. If you read this book.
Macros in Lisp let you write code that writes code. Quoth one of my professors in college, "Code that writes code is some of the neatest code there is!". I'll agree with that. Writing a whole database or a whole test unit framework in Lisp in 50-odd lines is pretty impressive. Lisp doesn't even seem like that concise a language, compared to Ruby for example. But it's powerful. I'm reminded of Haskell, where everything is recursion. When you start layering recursion on top of recursion, things tend to branch out and get "big" very quickly; that "bigness" equals power and efficiency, if used properly. That seems to be one of Lisp's strengths; it lets you do that pretty easily.
Well, a lot of languages let you write "code that writes code". Perl has eval() which can take a custom-built string of code and execute it somewhat dynamically. The thing is though, eval sucks. If it dies, it dies at runtime, not compiletime. And you can only put things together via string manipulation. Lisp's code-building macros are more "built into the language", for lack of a better term.
Ruby lets you do some neat things too though. I found this article to be a pretty good description. Ruby lets you throw blocks of code around all over the place, and the more I learn of Lisp, the more I'm reminded of Ruby, or the more I think of ways I could be doing things Lisply in Ruby. Ruby has the added advantage of letting you do all kinds of horribly powerful things at runtime. Chopping up classes and methods and rebuilding them as you see fit, etc. The book hints that this is something Lisp lets you do too, since so much of Lisp is actually written IN Lisp.
To draw a nice contrast, today I was forced to do a lot of PHP programming. Oh sweet Jeebus. It burns. I hate PHP with a passion. Lisp is wonderfully consistent. The parentheses do get on my nerves, but there's never any doubt what your syntax should look like at a given time. It's always parentheses. PHP on the other hand is both very verbose, and very inconsistent, which is the worst possible combination. It's never predictable or discoverable. It's impossible to program PHP without PHP.net open in another window to constantly look crap up.
Any time I'm forced to use a traditional for() loop now, I start freaking out. That is something Ruby and Lisp both thankfully avoid. Ruby's iterators are my best friend. Looping through an array copying things to temp variables seems so barbaric now that I've seen alternatives. It's just one of the little things that gets to you; in general in PHP I feel like I'm trying to build a scaffold with pieces that can't be cut to the right size. Ruby gives me pieces that bend easily, and Lisp gives me really tiny pieces that fit together in all kinds of interesting ways.