Crash!

Posted by Rick DeNatale Thu, 05 Mar 2009 17:00:00 GMT

Recently posted on Ruby Talk, under the title ‘This System Must have been Written in Ruby’

At 1950 feet (around 700 meters) the airplane’s left altimeter suddenly and mistakenly registered an altitude of 8 feet (about 2 meters) below sea level and passed the reading on to the automatic control system, Van Vollenhoven said.

But the autopilot reduced gas to the engines and the plane lost speed, decelerating until, at a height of 450 feet (150 meters) it was about to stall. Warning systems alerted the pilots.

It appears that then the pilots immediately gave gas, full gas, however it was too late to recover,’’ ...The plane fell into a freshly plowed field, striking the ground tail first and breaking into three pieces.

I assume the poster’s position is that this is the kind of thing that happens when non-statically typed languages are used to implement mission critical functions.

I use to hear the same argument about C++ vs Smalltalk, from no less a luminary than Bjarne Stroustrup, who was wont to say that he would hate to fly in an airplane whose autopilot might throw a doesNotUnderstand: exception because of a type violation.

Okay, I admit it, the static type zealots are correct. Static typing absolves the programmer from worrying about:

  • Conceptual errors in the domain model.
  • The fact that a floating point number is a poor approximation of a real number.
  • Incorrect mathematical formulae, either due to misunderstanding, or typos.
  • User errors.
  • Off by one errors
  • Buffer overflows
  • Bad input data
  • Adding instead of subtracting, or vice-versa
  • Hardware failures
  • Errors in concurrency control
  • Your favorite bug here
  • The need to properly test the system.

If you believe that, or any significant portion of it, let me tell you about this bridge between Brooklyn and Manhattan which I have to sell you!

And if you believe that and rely on that faith to implement mission critical systems, please feature it in your advertisements, and let us know what mission critical systems were built that way, so that the rest of us can avoid them whenever possible.

Get Real!


Trackbacks

Use the following link to trackback from your own site:
http://talklikeaduck.denhaven2.com/trackbacks?article_id=533

Comments

  1. Laurens Holst 21 days later:

    So your argument is that if there is one thing that increases reliability, but there are still other points of possible failure, it is worthless? Air plane crashes happen because of a series of events, not because of a single point of failure.

    Each point of failure should be reduced to a minimum on an individual basis. You can’t say that because there are other ways a program can fail that has not (yet?) been solved by placing predicates in the code, that doing so is not useful in reducing the risks.

  2. Rick DeNatale 21 days later:

    No Laurens, that’s not my argument at all.

    Putting predicates in the code IS useful. Having the compiler check predicates based on the kind of static type system found in most statically typed languages, and then relying on the ghosts of these checks once the compiler has ‘passed’ on the code is folly.

    Dynamically typed languages tend to perform those ‘predicate checks’ continuously at run-time almost by necessity. This gives a better chance of catching and correcting problems, or at least getting better diagnostics of failures when they happen.

    The really powerful tool in staving off failures is intensive testing, something which should be done in any language, and something which skilled users of dynamically typed languages have as a religion, whether it’s called test-first, test-driven, or behavior-driven design and coding.

  3. Laurens Holst 22 days later:

    Well, I think nobody’s argueing that static typing is some form of Complete Error Protection System™ :). That would be folly indeed. But I don’t see how only doing type checks at runtime makes things safer, besides the fact that you are not using them to their full potential so it would just be a waste of effort to add type predicates. You will only notice them when you happen to have a test for the uncommon case that the code path is run through with an incorrect value.

    But what static typing can give you is, as long as you do not abuse the system by e.g. using type casts, static typing can guarantee, prove, certain things at compile-time by deduction. This is a promise dynamic typing can not give you. By the way, Java checks types at run-time as well, no?

    In your reply I see again the often used argument by proponents of dynamic typing that think they can make up for the lack of type predicates by testing. Yes, testing is important, but it is still only part of the picture and not a Complete Error Protection System™ either. It is so easy to miss specific cases, in a program with thousands of variables.

    E.g. you can create a bunch of tests for something that outputs HTML, but then someone comes along and writes a & or a < in a field without a space after it, and you discover that despite it passing your tests, you forgot to escape the string. Turns out HTML silently corrected it in your existing tests which didn’t cover that specific edge case. It’s a simple example, but just to illustrate the point that tests not failing does not guarantee anything, you can never have complete coverage. Your tests may be focusing on the functional aspect and fail to cover other things such as proper escaping.

    Testing is good, but complete testing coverage is an illusion, something which dynamic typing proponents often make it seem. A static type system, for the part that it does cover, does so completely; it can be proven that given certain stated conditions, something will satisfy those conditions. So that is one less thing you need to hope your tests cover sufficiently.

    So basically I’m saying static typing + testing will be less prone to errors than no static typing + testing, because there is an extra layer of defense. Just like making a language/virtual machine that also protects you from buffer overflows, or a language where concurrency is a primitive of the language and where it is guaranteed to work, adds to the reliability as well.

    Anyway, I’m being a bit long-winded here :).

  4. Laurens Holst 22 days later:

    Also consider that someone who writes tests does so from his own background. There is a plethora of blogs out there that the author thinks he has sufficiently tested, only to find as soon as someone who does not use pure US-ASCII comes around that there are encoding errors. The tester, being of American background, probably never even thought of that. He probably can’t even input non-ASCII characters with his keyboard without resorting to arcane ALT-numpad combinations.

    If all of the systems involved were required to explicitly state what their input and output encoding were, a checker could match these up and give an error of the output of one system did not match the required input of the other. This can be checked at compile-time, and there is yet one less complex issue that the author needs to worry about having tested.

  5. Rick DeNatale 27 days later:

    Laurens,

    I think we will just have to agree to disagree. You still seem to be missing what I’ve said.

    I never said that the run-time checking done by dynamic languages was a complete defense against errors, only that a reliance on compile time type checking was, at best, a rather weak defense.

    I get the impression that you haven’t had that much experience with using dynamic languages for production code. I’ve been doing it for nearly 30 years now, and my experience tells me that an agile development approach which uses behavior driven design, test driven coding, continuous integration, and refactoring, is much better at producing robust systems than any other approach I’ve tried.

    It’s like Churchill said about Democracy, the agile development approach I’ve outlined is the worst possible approach, excluding all others.

    But that’s my personal opinion, you are certainly entitled to yours.