Hey, I took off and hid my "smug Lisp weenie" hat for a reason :).
Seriously, I replied to the second part of your comment. Lisp may be the pinnacle of DSL-friendliness, but, as you say, plenty of languages have various measures of metaprogramming support, and yet, as you note, those facilities tend to be universally disliked by the mainstream programming community :).
(I believe that another strong reason for this is that the mainstream programming community is, for better or worse, eternally stuck in the "cater to the newcomers" mode. Effective use of metaprogramming requires a deep understanding of more abstract principles behind programming and complexity management, and are indeed dangerous in hands of beginners.)
There's an effect I've witnessed that I dubbed the "insecure intermediate metaprogrammer". Developers who have a strong desire to prove that they are no longer 'intermediate' programmers start taking advanced language features and trying to apply them to the problems they are given.
The idea, as I see it, is that they think that at a later date they can go "I'm not an intermediate programmer, I'm an expert because I have used advanced language features like metaprogramming". At the time they will probably not admit that this is a surreptitious attempt at career building.
Metaprogramming, by its nature, is sort of like amplified programming - it can be very powerful and save on tons of boilerplate if you use it at the right time in the right place. However, with that power comes a greater potential to create an almighty steaming pile of code shit that is way more horrible to reason about than even the worst code written by the most junior programmers. The intermediate programmer will likely not realize this.
Moreover, the intermediate doesn't actually have the kind of problems it solves. Metaprogramming is useful for building frameworks and I've seen it put to good use there on heavily tested open source which has hundreds of eyes on it to spot every issue and keep its natural tendency to get out of hand in check. But, however much many developers really want to believe otherwise, building frameworks is a very niche thing. It needs to be done well, but it does not need to be done often.
So the intermediate programmers then end up creating a glorious code turd of magnificent proportions in an attempt to prove that they are really experts. This creates code that gives juniors and experts alike nightmares. The juniors get conniptions because they think that they're just too dumb to know what is going on. The expert will (hopefully) be furious and demand that the shit is cleaned up. Hopefully at some point the intermediate will achieve the zen moment of "knowing when, not how to use metaprogramming is the truly important skill".
I think part of it is just achieving enough self-confidence that you no longer feel you have to prove yourself. I'll admit to inflicting overly-clever code on a previous employer when I first got into Scala (roughly when my career was at the 4-5 year mark).
I'm a bit embarrassed about it now, and it's exactly as you said: The older devs were quite visibly annoyed with me, the less experienced ones deferential :)
I realized my mistake after I had given my notice at that job and had to walk another dev through a module I had written :O
I'm much better now. I've been programming in Clojure for almost 2 years, and I don't think I've ever once used a defmacro in my own code :)
I think it's partly that but I don't think it's purely about self confidence and it isn't limited to metaprogramming. I think it's also a market driven effect. Developers will see jobs advertised or that require doing X that pay a lot more than what they currently do and think "I should gain some experience in X so I can sell it at my next job interview". Most developers have probably felt this instinct at some point even if they're plenty self confident.
I don't think it's such an easy problem to solve because, whatever X is, developers will probably have to be a fuck up at using it first. Then they get good at it. The higher pay is going to keep them motivated to use it and it's not usually practical to tell programmers that they should put their career development on hold because it's torturing your architecture.
Furthermore, sometimes X will more or less do the job ok even if it wasn't strictly necessary. In that case, was it really such a bad thing?
Anyway, I don't see it as something to be embarrassed about. Everybody screws up and learns from it.
haha, this reminds me of a chunk of self rewriting machine code I wrote for the C64 (where such enhancements could be justified) Every time I wanted to expand on it I had to sit myself down and look at it FOR A FEW HOURS just to remember what the fuck was going on. And it wasn't even big. The hilarious thought someone else would one day try to decipher it crossed my mind hundreds of times. "Okay, so this is where the code generation rewrites it self.... again"
Sure, you can have conditionals but you can also replace them with no-ops and sure you can have no-ops but you can also move the lower part of the code up.... or should that be the upper part down? Which one is the bigger? How to keep track of this modification? surely moar code morphing is the answer?
Seriously, I replied to the second part of your comment. Lisp may be the pinnacle of DSL-friendliness, but, as you say, plenty of languages have various measures of metaprogramming support, and yet, as you note, those facilities tend to be universally disliked by the mainstream programming community :).
(I believe that another strong reason for this is that the mainstream programming community is, for better or worse, eternally stuck in the "cater to the newcomers" mode. Effective use of metaprogramming requires a deep understanding of more abstract principles behind programming and complexity management, and are indeed dangerous in hands of beginners.)