Of course, in Perl culture, almost nothing is prohibited. My feeling is that the rest of the world already has plenty of perfectly good prohibitions, so why invent more? That applies not just to programming, but also to interpersonal relationships, by the way. I have upon more than one occasion been requested to eject someone from the Perl community, generally for being offensive in some fashion or other. So far I have consistently refused. I believe this is the right policy. At least, it's worked so far, on a practical level. Either the offensive person has left eventually of their own accord, or they've settled down and learned to deal with others more constructively. It's odd. People understand instinctively that the best way for computer programs to communicate with each other is for each of the them to be strict in what they emit, and liberal in what they accept. The odd thing is that people themselves are not willing to be strict in how they speak and liberal in how they listen. You'd think that would also be obvious. Instead, we're taught to express ourselves.

I think my paraphrase fits the original context of this and other remarks by Larry.

It also suggests, I think, a rather simple solution to the "HTML problem." If browsers implemented a small indicator (or a toolbar button) that changed state when faced with malformed HTML (CSS, XML, or whatever), the person browsing the content could trigger a report of the problems. Something like this would be nice:

(It would be even nicer if the report could then be emailed to someone, such as the contact person of the site in question.)

Update for no_slogan: OTOH, it just might be impetus to fix the problems, donch'a think? Still, I was thinking of the idea for the people designing the site, then previewing the results. Given that, we could dispense with the email thing...just so long as the report is easily saveable to text.

This approach handles the problems that tye wants to prevent, provides an active solution, and lends itself to handling other problems that you (and Joel) mentioned. Consider:

When provided different interfaces, choose the one that best fits the specific context.

If none exists, then write wrappers to convert what you have to what you need...and then alert the author/maintainer to the discrepancy.

When presented with incomplete (or incorrect) input, recover if you can or fail if you can't.

If you fail, however, provide clear and easy-to-access information describing the failure and the solution to the problem.

Instead of changing the behavior of existing interfaces quietly, document those changes as clearly and broadly as possible or (preferably) create a new interface that offers the new behavior while calling the original. This lets you deprecate the original behavior while allowing existing code to run until it can be refit.

Instead of creating user-hostile tools that throw preferences, character sets, locale issues, and other problems commonly associated with international programming, create software tools that make it easy for the casual or untrained developer to deal with these and other common problems. IOW, make your libraries, modules, tools, componenets, and so forth as aware--and extensible--as possible. (While I agree with the basic sentiment that Joel was ranting about, I disagree with his conclusion. I prefer to test things heavily.)

Similarly, provide ways to test for commonly encountered problems and specific information on resolving them. Don't force everyone else to claw their way up the same learning cliff that you had to.

Given a specification (or contract, if you will) that doesn't specify what happens in a corner case, get that clarified by the contract sponsors. This would have been reasonably easy for the Netscape team to have done at the time and would have prevented, I think, a lot of the grief we're dealing with today.

When encountering code that erroneously relies on undocumented behavior, shouldn't you simply treat it as a bug and fix it, rather than blaming someone else for the problem? (It's not Larry's fault that some 'softie changed a Windows API call. Nor is it his fault that one of your guys relied on undocumented behavior.)

When you find a bug, fix it. (That's also part of the contract.) This includes legacy bugs, such as CSS Level 1 support (or lack thereof).

When faced with tools that do not satisfy their contracts, contact the responsible parties and see if they'll fix the problems. If they don't, then either find a workaround or use different tools. Period. Life's too short to worry about broken promises.

I do agree that Design By Contract is a Very Good Thing®; however, part of the contract is letting others know when the contract has been broken. (For more on the subject, I highly recommend The Pragmatic Programmer, which devotes a major section to the subject and also provides an interesting variation of Larry's comment.)

In short, I think Larry's spot on with his comment. We should forgive liberally, act responsibly, *and* communicate...just be nice about it. (Remember the last rule of perlstyle.)

Just because we're not good at something doesn't mean we should stop trying to practice it. There is, after all, only one way to get to Carnegie Hall.