On the futility of error checking (anecdotal)

Just a little anecdotal evidence for the futility of error checking, compile and runtime, no matter how sophisticated.

I initialized something to 1e64 instead of 1f64. It somewhat affected the results. By 64 orders of magnitude! :grinning:

The Rust compiler, always so full of complaints at other times, was of course happy with it.
As were all my runtime checks. How often do you test for legal values being 'just too big'?

It shows how all error checking, compilation and runtime, is doomed in the face of the slightest typing error.

3 Likes

This sounds like something that should be added as a lint to clippy if it hasn't been already. Any of 1e32 or 1e64 could potentially be typos (after all, 10⁢⁴ is an oddly specific power of 10).

5 Likes

Wow, what a beautifully subtle bug.

I great example of two apparently harmless language features conspiring to defeat you when combined in the same language. In this case exponential notation and type suffixes.

It's like the octal constants in C. When you accidentally write 013 instead of 13 and get 11 in decimal.

I'm not sure what clippy would be expected to say about that. They are both reasonable things to do.

6 Likes

Please, don't mix up your quantifiers for the sake of demagogy.

Your example shows that some errors can't be detected. It doesn't demonstrate that "all" error checking is "doomed".

If we are being nihilists, we might as well just not even try achieving any sort of correctness. I would not like to live in such a world.

16 Likes

I meant all error checking that this bug was subjected to and yet slipped through.
However, yes, it is a bit tongue-in-cheek. No demagogy intended.

Any language which offers conveniently terse syntax to do things will have the same problem. You can design languages so that no single character change will result in a valid program, but then you're making all of the language's syntax use multiple characters and it will be annoying to type and unfamiliar.

That is undoubtedly true but you can guard against few specific ambiguities (exponential notation versus type suffix) like this one. Maybe it is just me, my lifelong habit of using scientific notation, or the proximity of e and f in the alphabet, but I seem to mix them up quite easily.

Not wishing to make too much of this but sometimes it is as well to have some practicality as much as wonderous puristic principles.

I can well imagine someone shouting "All f'ing error checking is useless" in frustration when finding this bug after some hours of bug hunting. I would not expect they really mean it.

I haven't been a big fan of type suffixes. The look a bit messy to me, they hide the number in noise, for example 1i64. And what is this :

0x01e10f64

When I might mean this:

0x01e10f64i32

Ewww...

12 Likes

If one always writes suffixes with underscores, this kind of thing can be easier: 1e64 is plausible, but 1_e64 is weird enough to be reasonable to lint against.

This reminds me of

where the lint was added quickly, and is another place where that was only possible to lint thanks to the underscore -- linting on 432 would be too aggressive, but 4_32 isn't what people meant to say. (AFAIK 12_34_56_789 and 123_456_789 are used, but 1_23_45_67_89 is at least rare.)

5 Likes

Maybe I will just go back to good old:

let x:f64 = 1.0;

Somehow I do not think that adding alternative ways to write the same thing enhances the language. It only enhances ambiguities and confusions.

5 Likes

I tend to agree. Just say no to type suffixes.

Can we have a lint to point them out?

3 Likes

I wholeheartedly agree with that. They do have some theoretical benefits around type inference, but IMO that's the wrong tradeoff between a minor inconvenience and major bugs.

2 Likes

Oh, nice catch! The playground doesn't even syntax highlight the 1e32 style properly. This looks really bad: 1e32f32. If we could change Rust any way we wanted, what would be the best solution? Get rid of type suffixes or come up with a different "times power of ten" notation?

1 Like

Since the bug can only happen for e32/f32 and e64/f64 (and maybe 16 bit and 128 bit floats in the future), maybe the lint could be limited to those cases?

I would not be too sure about the 'only' part. However, if there are more bugs waiting, I am sure to perpetrate them.
How about 0x1e32, 1e32 and 1f32? First is integer 7730, second is float
100000000000000000000000000000000.0, same as your 1e32f32 but different type (f64), and the third is f32 1.0 :grinning:

1 Like

There is the thing. Mixing up hex notation and float suffixes generally produces a type that won't work in your program. You will get a type check error.

Where as your first example insidiously slips past type checking.

2 Likes

I like this idea, so why leave it to the writer to remember? It could be removed as valid syntax for literal suffixes.

I didn't realise rust actually allowed 123f32 I though it had to have an underscore. In the rare occasions when I want to use a literal suffix I've always used an underscore and it seemed sensible :slight_smile:

1 Like

I like the idea of making the underscore before the suffix compulsory.

Or at least having clippy shout when it is missing.

Apart from the potential bug avoiding, as in this case, it makes the use of suffixes more legible.

7 Likes

No, I'd argue it shows the importance of code review and tests.

Humans aren't perfect and we've all fat-fingered something only to have the compiler yell at us or crash at runtime. You can help avoid these sorts of things by having another set of eyes check your stuff or writing some smoke tests, but discounting all error checking as futile feels a little extreme.

I can totally relate to the knee jerk reaction though. There's more than one occasion that I've spent hours trying to debug a problem only to realise it was just me doing something stupid :stuck_out_tongue:

4 Likes

Yes, code reviews and tests are important.

But that statement sounds like the argument I get from C/C++ programmers when discussion of Rust, it's type checking, memory use checking etc comes up. "We don't need all that, we know how to code, we code it right, we have reviews and tests and procedures in place, we have sanitizers...."

Given that Rust is pretty much predicated on preventing a lot of bugs with it's extremely anal type checking and memory use tracking, I don't think it's much to ask that it help find silly typos like this where it's reasonably possible.

The compiler error messages and clippy are my only reviewers. Until such time I win my partners over to Rust. Clippy could suggest using an underscore in such cases, as it does when one names unused variables.

3 Likes