Hacker News new | ask | show | jobs
by fiedzia 3369 days ago
And I do. Planes crashed and people died because of buggy software. We have lost Mars climate orbiter due to not using type-safe language. In the cases of software that works fine, we are just relying on ridiculous amount of manual verification, and this is both risky and expensive.
3 comments

> We have lost Mars climate orbiter due to not using type-safe language.

One company creates a closed-source component that produces a float, another company creates a closed-source component that receives a float. Units differ. Crash. No type-safe language will prevent that bug from happening. Let 100 programmers write these programs in your type-safe language of choice and all will be vulnerable to this.

"Oh no", I hear you say, "we'll give every unit its own type" and it still won't stop your programmers from deserializing a 4 byte value in English units into the metric value they think it is. "So we'll make all the IO typed as well!" You don't need a type safe language to do that. And why would you do it in the first place? If your API spec says you receive a float in metric units, you write your program accordingly. When you're writing mission critical software, would you really want to replace a

> read(sensor, &value, sizeof(float))

with 100k lines of even buggier code to prevent a bug from happening that shouldn't happen in the first place?

> Let 100 programmers write these programs in your type-safe language of choice and all will be vulnerable to this.

Some will be, some will define inteface as float_meters and define automatic conversion from yards, avoiding whole issue.

All bugs "shouldn't happen in the first place", the use of types is to reduce the surface area for where errors can be introduced. If you read some value from an external source and subsequently use measure types then you've isolated the scope for the introduction of errors to the read function instead of every location in the program that uses the value.
Mars Climate Orbiter was lost because they forgot to convert units between different systems. That's an error that can (and probably would) be done in all type-safe languages I know of.
That looks useful. I do not know F#, but can't you still use ordinary float and have the same bug?
Sure, unit wrappers are much more like "memory safety checks" in C, in that they are incomplete and can be bypassed. In that sense, the war against raw types is necessarily a cultural one.
It could be prevented if you could express units in the type system. Declare numeric_value_in_meters and numeric_value_in_yards as types and problem solved. Sure, it still possible that someone would not do that, but having this option is statistically better than not having.
You can do that in C struct Meters { int value; }
No, it's not statically checked for correctness.

Example of successful compilation in C Language which is semantically wrong: http://ideone.com/Hdd4Sh

(No casts required.)

It's only your opinion that the code is wrong based on the interpretation of the program's identifiers through an English dictionary. It is well-defined ISO C. Even the termination status is well specified, since the float value will truncate to 0, which is EXIT_SUCCESS.

Any program in any language can be regarded as not having passed checks for some imaginable something.

A perfectly good poker game is semantically wrong because the customer asked for an accounting application. The compiler should have checked the code against a formalized version of the requirement spec, damn it!

>It's only your opinion that the code is wrong based on the interpretation of the program's identifiers through an English dictionary.

No, that isn't quite right. I'm the one who authored that code example so even if I used opaque non-English struct tag names such as "struct s1{}" and "struct s2{}" instead of "struct meter{}" and "struct inch{}", my brain intended for s1 and s2 to not be mixed and matched carelessly. Poster mikulas_florek suggested wrapping plain ints with a struct and my example shows that that workaround doesn't accomplish what he says it does.

>It is well-defined ISO C.

Yes, and I wanted to emphasize that truism by showing a live example of a successful compilation in ideone.com!

I thought the thread was about higher-level semantics rather than the set of trivially true sequences of text input that the compiler accepts.

It's hard to discuss this without using any specific "type-safe" language.

1. you can have the same problem in type-safe language, since it will probably have cast to int too 2. do not use builtin operators in C for that, instead create new functions, e.g. addMeters(Meters a, Meters b); 3. hide the int in *.c file

Look at the common theme among your suggestions:

  - do not use builtin operators in C for that, 
  - instead create new functions, e.g. addMeters()
  - hide the int in *.c file
Those are "best practices" instead of compiler-enforced type-check errors. Likewise, suggesting a best practice such as "don't free() memory twice" is not the same as a GC-language (Lisp/Java/C#/Go) freeing memory on the programmer's behalf or a static-ownership checker (Rust) preventing a programmer from making that mistake.
> you can have the same problem in type-safe language

Yes, you can. But at least you have a better option and better chance of other people using it, so statistically you'll have less errors.

> do not use builtin operators in C for that

No, do not add another rule to a million of rules people have to already follow, make compiler worry about enforcing that, not developer.

Yes, although you should probably do struct value_in_meters { int in_meters; }, so that e.g. x.in_meters / y.in_inches (will compile, but) looks as wrong as it is.
Yes, but nothing will stop you from casting pointer to meters into pointer to yards, while many C features force or encourage this behaviour. You also cannot override operators for combining those units. And the value is still just int.
> casting pointer to meters into pointer to yards, while many C features force or encourage this behaviour.

What C feature forces or encourages casting Meters* to Yards*?

> You also cannot override operators for combining those units.

The lack of operator overloads has nothing to do with typesafety. There are languages which are considered typesafe and which do not have operator overloading.

No amount of 'type safety' will prevent idiots from being idiots, and with all the other languages, the problem is very often sitting on the chair. People will screw up creatively in any language, and trying to 'hide' that behind a language runtime overhead is idiotic. The good thing with C is that it will catch the worst idiots quickly, so you know not to hire them to write avionics for you.

What is NOT idiotic iswhat you discribe as 'ridiculous amount of verification' as it's often the only thing that will really work to catch mistakes.

> No amount of 'type safety' will prevent idiots from being idiots

But it will limit the damage they do considerably. Having bit of space or trees between lanes on a road saves a lot of lives, even if people drive as idiotically as they would without it.

> What is NOT idiotic is what you discribe as 'ridiculous amount of verification'

Designing systems that rely only on that is idiotic when there are better options.