False robustness and needless adversity
Perhaps while tearfully washing dishes in my kitchen as part of an extended expression of genuine contrition, Douglas can explain to me why he keeps writing about object users as "attackers" and "tamperers". Maybe it's a reflection of childhood trauma that manifests itself as a pathological distrust that he's struggling to overcome. I do not know the answers, yet. Web programming (which I am very new to) is full of security concerns - malicious users will try to compromise your site or fellow site visitors with bogus inputs. They might take your scripts, modify them, and try to use the modified version to molest the backend in twisted ways. But a fellow coder - someone who's just using the random library you wrote - is not your enemy.
As someone who comes from a C and C++ background, and is all too familiar with memory errors, I am not taken in by this false sense of security. Once something has accidentally overwritten the properties of your object, you are fucked. The error has happened, it is something we speak of in the past tense. Being "resilient" to the error is merely poorly hiding its existence. The only way to be 100% resilient to having some property overwritten is for that property to not matter. In that case, why did you have it in the first place? (And that's where private variables come in -- by making your variables private, you make there be less stuff to accidentally clobber).
The greatest insult: floating point
But somehow, I don't think Douglas is asking for a software floating point implementation. I think he's profoundly upset that information is not being stored precisely. Douglas, maybe you would be happier using Mathematica. Because a symbolic algebra package is the only way you can actually ever avoid every class of this problem. Sure, you can fix 0.1 + 0.2 = 0.3 by using a decimal approximation. Next thing he'll want is 1/3 + 2/3 = 1. Or sqrt(20)^2 = 20. There's no end to this. Maybe we should turn Maple into a Firefox extension.
And here comes Douglas, with a bone to pick. He think he knows better -- why can't math on a computer just work right? Fuck you, Douglas. Before you apologize to me for penning this travesty, please travel around the country, apologizing first to Kahan, then to the other IEEE 754 architects.
Appendix: Supplementary apology for incorrect philosophy
As an addition to the above essay, I'd like to make some comments on Crockford's language design philosophy. In Chapter 10, Beautiful Features, Douglas waxes poetic about language design, feature creep, and what makes a language beautiful. Unfortunately, his argument boils down to "Features that offer value to a minority of users impose a cost on all users". With some word substitution, this sounds like some sort of ultra-libertarian political screed against funding for leukemia research.
I think Douglas owes cancer sufferers an apology (While the offense is not great, I think he should apologize to them first, because they might not be around that long.)
On the surface, this argument for simplicity makes sense. Of course we want to get the core parts of a language right. Of course features need to be specified and documented. Clearly we should go back to basics and use something that "just work[s]". But on any depth of reflection, this is empty platitude and nonsense.
There are a thousand languages out there, and dozens new every year, that perform "hello world" in three lines. Languages that let you write state machines and web servers in simple, elegant ways. What differentiates these languages (besides breadth of platform and library support) is not how good their "cores" look. They're divided by three differences:
Adaptability to new problems. Of course, if you're writing simple example apps for a book, having a cat object say "meow" is all you need to think about. The reader smiles and nods and turns the page. When some new application or platform comes along and we ask a language to stretch - that's when its mettle is tested. It has to have a great core, yes - but that's not enough. (A lot of languages fail this because they fail to adapt to multi-threaded environments, for example).
Uncommon use cases. You start writing some little spreadsheet app. You let the user add up numbers, and its great. Before you know it, it's popular and used by a lot of people. A company asks you to make them a version that can solve linear equations. And then tells you to fuck off because the answers you're providing don't add up. Guess what? Without decent floating point support (exceptions, ulps, etc), it's hard to write robust code. You didn't think you'd be in this game when you started -- it was just another web app -- but projects change. Think of this as voting to cut NIH funding and then getting rib cancer. Cancer of the ribs.
Unobtrusiveness. And this is where Crockford has it right -- while you have to have support to be adaptable and to handle uncommon use cases, you can't let those get in the way of writing simple code when you're just trying to get something done. But just because you have a feature doesn't mean it has to be annoying. You just have to design it well.
Thanks to a correction, I've changed "strong types" above to "static". That is what I meant to say (I keep making that verbal mistake).
While rational numbers do solve the 0.1 + 0.2 and 1/3 + 2/3 problems, they do not solve the sqrt problem (which I've re-written above to be more clear and correct (I had the square inside the root instead of outside and used a perfect square).
Thanks to a reader whose comment I can only see in email, for whatever reason, for pointing out IBM's specification for (nearly) IEEE 754 compliant decimal arithmetic. If you're really into your cents being cents, this may be for you.
I've decided to remove two "Cockfords" and replace them with "Crockfords". Being thoroughly lambasted on purely technical grounds is not nearly penance enough - hence the apology and dishwashing - but Cockford didn't really fit in with the vibe I was going for. But you're totally thinking it now.