Larry Wall famously lists three great virtues of a programmer: laziness, impatience, and hubris. I should like to add ingratitude.

The common understanding of Wall's virtues is as vices or faults of character. Young programmers are amused; perhaps dangerously, their poor and careless habits are endorsed; perhaps they are emboldened to do Good. Old programmers reflect on the exceptional nature of computer programming as technology, art, and culture; and may see merit in both interpretations.

I suggest ingratitude has a similar, dual nature. I define this here as the unwillingness to accept gifts and unexpected success. Rather than thank $Deity, Fate, or even a fellow engineer's forethought, the superior programmer looks with disfavor on things that work right when they should fail. Success due to unknown causes may be fragile and is suspect.

Therefore the virtuous programmer is ungrateful. He looks the gift horse in the mouth. She sees the routine that handles more cases than planned and hammers it for weakness. We bite found gold coins.

As have the first three, the virtue of ingratitude has a vicious nature, too. Failure to accept something that does, indeed, work and work well can lead to something perfectly robust being thrown out, or excessive time wasted building a more perfect substitute in a demonstration of false laziness. But the commonly-prescribed, inverse quality of gratitude serves the too-trusting programmer poorly. The minimum wise reaction in case of an attractive wooden horse found at the door is to study its documentation before towing it inside.

Boring Personal Anecdote

About four weeks ago, I decided to hack into Smart::Comments to have it accept alternative filehandles for output; the Vanilla version (1.0.4) prints only to STDERR. Particularly, I want to be able to log smart output to a hard disk file. I consider Vanilla a lightweight debugging tool, not for production; I thought the project a simple hack.

Well, it's a source filter; and its author, TheDamian, has perhaps taken liberties in its construction which he does not prescribe to others. Still, how hard can it be to replace every instance of print STDERR with print {$outfh}? And oh, there's the issue of getting and setting that $outfh. Turns out there's much more to it.

Still, I made surprisingly good progress in just a couple of hours. I wrote a few tests and they passed. I didn't use an elaborate testing framework, since I felt the accumulated weirdness of testing a source filter inside TAP::Harness was sufficient. I copied one test script to another and elaborated.

All went well until I actually got to the point of supplying a hard disk filehandle, opened for writing. This *almost* worked right but the file written had just a couple of newlines fewer than output to STDERR or even STDOUT under the same provocations. Since the test script strictly compared the output, it failed. The expected output, literally written into the script, was a duplicate of the expectations in prior tests. Where did these two newlines go?

S::C outputs gratuitous or prophylactic newlines under some conditions; I've spent much of my working time on this, trying to figure out or control when. I got to the point of a long-winded CB ramble on the topic. I worked on other issues. I played with fire, using an untouched copy of Vanilla to reverse engineer my working copy -- using a source filter within a source filter. I wrote an essay in defense of S::C. I groused, sulked, annoyed people. I set the project aside for a week.

By the time I returned, it was clear to me that I didn't want so many newlines in disk file output anyway. I'll beat you to the punch and admit that I still have not figured out what's causing more newlines to print to STDERR than to the disk file.

In pursuit of my two missing newlines, I have been over every line of S::C. Even after the week off, I spent much time looking for those newlines. I've torn up Conway's original code, broken out subroutines, tackled several unrelated tasks, and tinkered with every single place where the module might emit anything, anywhere. I've written enough comments -- boilerplate, algorithmic, elucidating, defensive, indicative, and discursive -- to launch an intercontinental ballistic missile. I added the entirety of Vanilla's original test suite to my own.

My original plan was to diddle the original code as little as possible; leave the complex stuff alone since, after all, it works already and it's way above my level. I meant only to add a feature, not to rewrite old ones. Instead, I've come to understand S::C much better than I planned; and I hope I've brought the code to a more maintainable state.

Finally, I caved in and moved the goal posts to where I wanted them to be anyway. All current tests passed, Conway's and my own. I became grateful that chance or fate had eliminated newlines where I didn't really want them anyway.

After much more refactoring and indeed tearing up my whole approach to storing state, the gratuitous newline issue has resurfaced, with wheels on. I have no alternative but to track it to its source and fix it (still TODO).

The point is not that I'm clever or even hard-working; I'm not. The point is that my ingratitude, my untrusting nature, my unwillingness to accept the gift of the module working unexpectedly well, is what drove me to overcome my inexperience and ignorance, to rise to the challenge.

When I became grateful and falsely lazy, I stumbled.

- the lyf so short, the craft so long to lerne -

Replies are listed 'Best First'.
Re: Ingratitude, the Fourth Great Virtue
by jdporter (Paladin) on Jun 29, 2010 at 14:04 UTC

    You don't say so, so I wonder: did you ever ask Damian for help?

    What is the sound of Windows? Is it not the sound of a wall upon which people have smashed their heads... all the way through?

      Well, that's tangential to ingratitude.

      No, I haven't. My mechanism for generating the gratuitous newlines is not Vanilla S::C's, anyway. ::Any has become a fork and a complete overhaul; there's not much untouched Vanilla code left by now.

      - the lyf so short, the craft so long to lerne -
Re: Ingratitude, the Fourth Great Virtue
by pemungkah (Priest) on Jul 02, 2010 at 00:01 UTC
    I might call it skepticism instead of ingratitude; it's an unwillingness to unthinkingly accept something you did nothing to get, as opposed to accepting something without acknowledgment and then treating the provider badly - since there is no person involved, just a computer.

      Some (not I) would speak of gratitude towards God, Fate, or a benevolent Universe. It is this sort of gratitude that is urged as a common virtue, along with platitudes /[everything happens for a reason|just go with the flow|it's all good|it was meant to be]/ and my personal favorite, It must have been written! The opposite tack, with its stubborn self-reliance, its sub rosa resentment of and hostility toward any suggestion of supernatural paternalism, is the one I here uphold; somewhat harder into the wind than mere skepticism. The ungrateful engineer does not merely look into the mouth of the horse found wandering in the dooryard; he rides it hard to town and back before giving it hay.

      Ingratitude is not skepticism for the same reason that laziness is not forethought, impatience is not creativity, and hubris is not dignity. The last are virtues common to all; the former for programmers alone, maybe only programmers who write in a postmodern language. (There may be other specialists who benefit from these but I can't think who, right now, except perhaps the owner of a liquor store in a tough neighborhood.)

      I endorse gratitude towards generous humans who design free tools that work unexpectedly well. Failing to say Thank You! when appropriate is mere boorishness and false ingratitude.

      - the lyf so short, the craft so long to lerne -