Pause for crickets and tumbleweed...
Huh. Apparently, feeling dumb is not particularly popular. Who would have guessed?
Let's try a little experiment. I want you to imagine that you and I are in the same room, discussing something. You've just put forward some extensive effort and invested a lot of time and energy in some particular project. Let's say it's a really complex and intricate bit of code. I've just looked at your work, and I've taken a deep breath, about to express my reaction and opinion.
Now, get a good mental image of me, and imagine that I'm looking you in the eye. I want you to imagine this vividly - actually hear it - when I say the following words:
How would you react to that? Be honest.
No, don't bullshit me. I said be honest. That's right. No lies. (If it helps, remember that this is all hypothetical and in your head - I won't really know. And unless you're screaming in rage and violently introducing your monitor to the floor, nobody else will know either.)
It's interesting (to me at least) how varied people's reactions are when they're confronted with some attack on their intelligence. It may not even be a real attack - even perceived slights can inspire all manner of powerful responses in people. Some will immediately enter denial-mode, offering all manner of excuses and rationalizations to back up their side. Some will become hostile, going on the attack, a sort of "you can't discredit me, I'll discredit you first!" attitude.
Even more interesting is how people tend to conflate intelligence with correctness. If someone says you're wrong, more often than not it will be interpreted as you're stupid. Try repeating the little thought experiment from earlier, except this time substitute the word "wrong" for the word "stupid." Do your feelings change? Do they change significantly?
On occasion, quite rarely, we run into an interesting sort of person: someone who understands the difference between being wrong and being dumb, even when it is they themselves who are wrong; someone who can be directly told, to their face, that they're wrong (or even stupid!) and not become hostile, angry, defensive, or generally unpleasant.
I am not that kind of person.
I don't have much going for me - no ravishing good looks, no Herculean physique, no superpowers or influential relatives, no particular ability to cook. The majority of my ego is rooted in the belief that I'm not stupid. This is, fundamentally, a pretty ridiculous state of affairs, because in point of fact, I am stupid.
There's an interesting principle that affects all forms of growth, and it holds just as much for muscle-building as it does for intellectual skills: if you do not stretch beyond capacity, there will be no growth.
You can't increase your muscle mass without increasing the work you make your muscles do. You can't increase your interpersonal skills without meeting new sorts of people. You can't increase your vertical jump without progressively ratcheting up the bar and forcing yourself to go higher.
You can't become a better programmer without stretching your abilities - working in a domain you do not know, working with a tool you do not know, working on harder or larger problems.
The principle itself shouldn't be news to anyone; it's cited often enough, and certainly the kinds of people liable to read a journal like this already know it. There is an important corollary to this principle, however, which is not mentioned so often: you can't stretch your abilities if you don't know your own limits.
But, you may object, that isn't really true; after all, I can just tackle some ridiculously hard project, knowing that it is well beyond my limits, even without knowing exactly where my limits are.
Technically, that's correct; but it isn't really a practical way to try to grow. Setting one's sights too high is never productive. It leads to disappointment, disillusionment, quitting, and maybe even severe injury. Pretty much everyone knows they can't lift a bus, but nobody tries to lift buses as a way to bulk up for swimsuit season.
The trick to growth isn't to stretch yourself so much that you rip apart under the stress and fling sticky bits of goo all over the room. The trick to growth is to stretch just beyond your limit - enough to be uncomfortable, enough to be noticed, but not enough to cause outright injury. We lift barbells, not buses.
The hardest part of knowing your own limitations is acknowledging them. I think that, to some extent, everyone knows deep down what they are and are not capable of. It may be buried way down there, but there's always the quiet voice of reason that says you're in over your head.
What's hard isn't getting that voice to talk. What's hard is listening to it.
I've been programming for something like 15 years now. One of my greatest regrets is that I haven't kept much of my older work; almost all of my original code is long gone. But I have preserved a few fragments, a few snippets of memory here and there.
There's one in particular which is a sort of paradoxical thing; it's immensely embarrassing and even painful to read, but simultaneously deeply valuable. It's one of my favorite reminders of my own stupidity.
Scribbled in pencil in an ancient spiral-bound notebook, there's a page with these words:
Hi, I'm Mike, and I know pretty much everything about programming in QuickBasic.
Every few years, as I shuffle my personal possessions around for various reasons, I come across that notebook. And every time I've opened it and read that horrible sentence, I've had pretty much the same reaction:
Ugh... shit! Did I really write that?
For the first few months of my hacking career, I knew my limits. I knew that there was a huge amount to computers, technology, programming, logic - and that I had barely scratched the surface. I knew it was hard, that I didn't really know what I was doing.
I knew I was stupid.
Somehow, over time, I lost that - to my own detriment. I learned fast, and wrote a lot of code. I can't say it was particularly good (hell, it was QuickBasic), but it wasn't terrible. And somehow, I let myself become convinced that I was no longer stupid.
The next time I really felt the burn of my own stupidity was when Windows 3.1 finally started to gain popularity, and I moved into the heady realm of Visual Basic. I had the cutting-edge, hot-off-the-presses 3.0 version, and it was incredible stuff. Windows was a totally different realm, and I once again was forced to confront the fact that I didn't know much.
Mercifully, the second time through the cycle, I didn't get quite as big-headed. Even once I'd produced (and sold) a couple of decent, small VB apps, I never did get to a point where I believed that "I know just about everything." I thought I was pretty hot shit, but I only had to look at that old notebook to be reminded of just how limited I really was.
The next big leap was C, and it was a bugger. VB had its pitfalls, especially in the old Win3.1 days, but it was nothing compared to C and 32-bit DOS extenders. (I feel old just writing that phrase...) Memory models? Near and far pointers? Interrupt vectors? VESA? What the hell is all this stuff? I was stupid - really, profoundly stupid, and it lasted for a while.
It's interesting to me that I never really did reach a point where I felt non-stupid in C. Certainly, I got comfortable and confident, and even became fairly productive. But there was always a nagging sense that the language - or, more accurately, the things you could do with the language - comprised a realm of knowledge much larger than I understood.
I'm not sure I can really credit myself with this newfound grasp on reality. I think the biggest influence was the Internet; I only really left VB for C around the time when the Internet was populous and accessible enough that I had easy access to other people's code. It never seemed very hard to find C code that blew my mind. In the early days, I'd only very rarely glimpsed anyone else's work, and I think that made it much easier to develop delusions of grandeur.
My early time in C lead inexorably to C++, of sorts. In those days, Win32 programming was done with direct API calls, and it was not pleasant. I remember when MFC finally became somewhat stable, and people started thinking of it as ready for "production code." It was such a huge breath of fresh air, and a glorious relief from direct Win32 API programming... but it required this new, weird, strange beast of a language, this C++.
Unfortunately, due in part to the rather unstandardized nature of C++ at the time, and due largely to the fact that MFC was really a pretty piss-poor C++ library, I developed a lot of misconceptions about the language. It seemed like C with some interesting, but largely annoying, extras bolted on. In the end, it was worth putting up with this weird C++ beast, if only because MFC was so much more convenient than the alternative.
So it was that I didn't really know C++ ... but I knew MFC, and that was enough to score a job. It was, ostensibly, a C++ programming job. The project wasn't the largest or most complicated thing I'd worked on by any means, but it had an interesting and annoying new dimension to it: maintenance. Unlike anything I'd done before in C or C++, I inherited a large block of code from someone else.
I quickly found out that there's a huge world of difference between working code and good code - good code adds the immense requirement of also being maintainable. The code I had was working, barely. It was not, by any stretch of the imagination, maintainable.
The solution, of course, was to rewrite it - but by that point I'd seen enough glimmerings of what real C++ should look like that I had my doubts. It wouldn't be enough to just rewrite it in the half-C slop style that I'd favored up until then; I figured, what the hell, I'm rewriting this application, I may as well go all the way and learn what real, good C++ is like.
And, once again, I was smacked in the face with a fact that had never really changed, but I'd somehow managed to ignore: I'm stupid.
In the intervening time since that project, I've learned a lot - about C++, about good software design in general, and about my own abilities. But I've once again gotten comfortable, slowly allowed myself to believe that maybe I'm not that dumb, that maybe, just maybe, there's a little bit of competence hiding somewhere in there.
One thing I've always sorely regretted about my own newbie-days in programming was the lack of mentors. With the (relatively) newfound tool of the Internet, it's suddenly possible to fill that role for a new group of beginners and learners, and I enjoy the opportunity to do so - partly because I like being helpful, and partly because it helps fuel the voice of the ego, which is continually saying you're not dumb.
The ego, however, is a lying son of a bitch - and that is how I came to post a really needlessly overcomplicated and generally crap solution to someone's question. Then, along came someone who is very much less stupid than me (thank the power of the Intertubes), and pointed out just how dumb my solution was.
There's a point to all this (and yes, I know I took my damn sweet time getting there). Once upon a time, back when I wrote really dumb and arrogant things in spiral-bound notebooks, my youthful ignorance would have prompted a certain response: "pfft, piss off, my answer's fine." I probably would have tried to invent some excuse as to why it was more robust, or made it more clear what was going on under the surface, or something - I don't know. (Thankfully, my bullshitting skills have found less and less use over the years, and seem to finally be atrophied to the point where it's not worth trying to lie anymore.)
At other times in my career, I would have responded in another way - by quietly disappearing and pretending nothing ever happened. The Internet allows a unique form of bailing out on an embarrassing situation. In real life, you have to at least endure the "walk of shame" and feel the burning stare of everyone on your back. On the Intertron, you can just vanish.
What really surprised me wasn't that I'm stupid. That knowledge lurks under the surface, and is never really too deeply buried. What surprised me was my first reaction - not anger, defensiveness, shame, or denial.
My first reaction was why didn't I think of the cleaner solution myself? There's nothing fundamentally unknown in Zahlman's improved code; I use the similar stuff all the time. I wrote a somewhat similar blurb of code earlier this very week. So why was my first response such a convoluted, horrible, idiotic, palaverous mess?
There's something important to learn from this, I think. I'm still stupid; I doubt that will ever change. But I've become, over the years, much more accepting of that fact. I finally know and acknowledge my own limitations, and as such I'm prepared to grow.
But clearly I'm not mindful enough of those limitations. If I really truly did know my limitations, I would have paused before posting the answer, to consider if it was really as good of an answer as I thought it was. It shouldn't have taken much consideration to realize that it was not, in fact, a good answer.
The final conclusion has pleasing Zen quality: I am stupid. I know this fact. I accept it and am, at least on some level, conscious of it.
But I'm still stupid about it.