> By saying metaprogramming is an anti-pattern, we're saying that us lowly programmers ought not to put on our language designer hat and let the professionals take care of it.
I don't agree.
For example, most of us here would probably classify manual memory management as an anti-pattern. We're capable of doing it; we do it when we must. But we recognize that, most of the time, it's a bad idea.
Perhaps vinceguidry is saying something similar about metaprogramming.
An anti-pattern is not a synonym for "bad code." Too many in this thread are making that mistake. A software pattern is a tool used intentionally to help better structure your classes. It's usually well-studied by people smarter than you are, the edge cases accounted for and documented.
An anti-pattern is a solution you find yourself using unintentionally that you notice is causing you pain later on down the line. The first 10 times or so you just fix the pain, you don't start noticing it until instance 20 or so. If you were to study that anti-pattern, you could figure out why it's causing you pain, and maybe even solve the pain points and turn it into a real software pattern.
If I'm doing exploratory programming that I don't expect to have to support or maintain, sure, I'll use all the power tools I can get my hands on to do cool shit with. But when I'm working on systems I don't care personally about, I want as little friction as possible between problem and solution. I don't want to have to look at a piece of code and wonder, "WTH is that doing again?" I notice myself having that reaction far more when there's metaprogramming involved than when there's not.
It's not that there's no way to use metaprogramming effectively or maintainably. It's just that I have to think that much more carefully about proper separation of concerns, how the messages are passing, what happens when there's errors, stuff I don't have to think about when I'm doing it the boring way. When something goes wrong in boring Ruby, the backtrace is all I need to figure out what's going wrong.
I've had the experience way too many times, of, over a dozen or so refactorings of a piece of metaprogramming I was too proud of to rip out, finally realizing that there was a bit of state I could have passed in a perfectly normal fashion that would have completely eliminated the need to, say, do dynamic class generation. Had I not been so hung up on my own brilliance, I could have saved myself hours of effort.
Likewise, if you find yourself reaching for manual memory management, that is, rolling your own management structures rather than using one of the countless well-tested constructs available, without really understanding why, then you're probably overlooking some library you could use that would do exactly what you want it to do and handle all the myriad edge cases had you given it some thought. I would absolutely consider manual memory management an anti-pattern unless you're working in embedded environments or demoscene, and sometimes even then. C is way too mature for you to be reinventing things.
Programmers are some of the most masochistic professionals I've ever met. They don't want to do things the easy way, easy seems to equate to stupid for them. You're not Linus Torvalds, the stakes just aren't that high. An .8kB in superfluous code loaded up in memory alongside the .2kB of the library you do need isn't going to kill you, only keep you sane. Don't make unnecessary work for yourself. Finish up early and go home and spend time with your kids.
To be specific, I find it an antipattern to think that memory or other resources can be pushed behind some lexical tricks. You still had better be able to account for your resources, in all places. Having first class control over them is often a matter of when you will need it, not if.
This is a classic case of overgeneralization which we programmers tend to do. Depending on the subfield that we work in (and sometimes the concrete problems), manual memory management can range from totally useless to always necessary
I don't agree.
For example, most of us here would probably classify manual memory management as an anti-pattern. We're capable of doing it; we do it when we must. But we recognize that, most of the time, it's a bad idea.
Perhaps vinceguidry is saying something similar about metaprogramming.