Take 20
This one is another slightly philosophical writeup that honestly doesn’t include any useful information 😇. But yes, it is (slightly) Rust related, don’t worry.
Like many people, when I was younger, I used do play
D&D. If you don’t know
what that is, it’s one of these role-playing games where people sit around a
table with bunch of papers and dice and pretend to be warriors and wizards
trying to survive a lot of really unsafe
things.
There was this one thing called a skill check. If you wanted to do something non-trivial, for example opening the locked bathroom door, you’d roll a 20-side die, add your skill score for that skill (the character had better training for some skills than for others) and compared it with difficulty of the task. The Dungeon Master (one player playing the rest of the Universe) set the difficulty based on some recommendations from the rule books (opening lock: 7, it’s dark: +5, the character has the right key: -5, the character really needs to pee: +3).
But there was another option besides rolling the die. It was called Taking 20. The idea was, the character would be trying again and again for a long time. But to save the real players from rolling the die many times until they eventually rolled 20, they’d just assume they did, in the exchange of the in-game time for bunch of attempts.
However, to be allowed to do that, you needed three things:
- Have enough time to actually keep trying a long time.
- Failure mustn’t be penalized ‒ so, no, you can’t take 20 for diffusing a bomb or for jumping over a pit. You just can’t retry that.
- The character could recognize success from failure. Opening a lock is in this category, but trying to forge a document or understand a text in foreign language probably wasn’t.
And now I’m getting to the philosophical idea. Is programming a skill you could take 20 on? Let’s say it’s a weekend project, so you can take as many weekends as you need. Failing is OK too ‒ a bit frustrating, but apart from that, you can always keep trying.
So, it’s mostly about this. I wrote some code. Do I know if the code is correct? Or, to avoid the „No code is ever correct“, let’s say, is it correct enough for whatever I need?
We have cases where we are sure the answer is „No“ (the thing either doesn’t
compile, or crashes on the first attempt). But then, there’s the gap between the
program working and the program appearing to work. With C or C++ and UB, the
gap is pretty large. Well, with unsafe
Rust probably too ‒ I just fixed an UB
and then went to prove the compiler couldn’t have taken advantage of it in
practice. All that after the code happily went through some amount of use and a
lot of stress-testing.
Anyway, how about Safe Rust? Do you think the gap is small enough for practical uses? If it compiles, does it work? When do you consider your code to be correct enough? Can this gap ever be closed completely? Or is our whole industry doomed to rely on a roll of dice forever (or on enough coffee on a Monday morning)?