(Note: "Hello World" doesn't count. Yes, it's possible to write an entirely bugfree Hello World. Duh. I'm talking about software packages larger than ten thousand lines.)
2) Is it practical to write entirely bugfree code? Why or why not?
I, personally, am inclined to believe the answer to the first one is "yes, maybe", while the answer to the second one is "no". There's a lot of things you can do to help eliminate bugs - perfectly-documented input/output prerequisites, tested with assertions, for example. However, the very nature of bugs makes them spring up in places you weren't expecting. Unless you're writing truly trivial software you probably have complex logic in it somewhere, and people make mistakes. The real causes of bugs aren't the things you could have protected against if you'd spent an extra few minutes writing asserts - they're the things you never would have even thought about.
I think to proclaim software entirely bugfree you have to have completely insane design methods. I read that there was some software design group (for the Space Shuttle or something equally high-profile that Absolutely Had To Work) that ended up with literally pages of documentation on every *line of code*, with multiple pages of documentation for suggested changes or bug fixes. Something that most coders would just do automatically, like making a parameter 32-bit instead of 16-bit, would have to go through a gargantuan review process to make sure it wouldn't possibly break anything. And even *they* got bugs, they just got fixed quickly (well, ignoring the review process :P)
If you've got that much money to blow and you *still* can't completely eliminate bugs before they creep in, it seems impossible to ever be able to say "Our code has zero bugs, we guarantee it." So here's the thing I'm wondering about - why don't people put more effort towards handling and detecting bugs, rather than just ignoring them or pretending they don't exist?
And I'm not talking about "check every return value". That's ludicrous. You're talking about a hundred extra lines of code in a medium-sized function, with half of them being "display error message and abort". But there's a lot to be said for "crash instantly with vaguely helpful error message", and there's also a lot to be said for "log error, try something else". Both of them are great in their place. So why does nobody do 'em?
I used to laugh when a game spat out an assert error at me - now I cheer!
(Well . . . sort of.)
(For the curious: an "assert" is a line of code that basically says "at this point in the code, this must be true". For example, "set X to 5, add 2 to X, multiply X by 4, assert that X is equal to 28". If X isn't equal to 28 at that point, something has obviously gone horribly horribly wrong. They're very handy for testing whether your program is sane or not.)