Hacker News new | ask | show | jobs
by Sharlin 2674 days ago
> I find it odd that some things like slice reads can still panic by default. Yes, I can use `foo.get(1)` to avoid panics, but still - it's a bit odd to me.

Panicking is a perfectly good way to handle the situation where an invariant of the program is violated. That is, it is perfectly fine to index using [] in cases where there cannot possibly be an out-of-bound access unless the program has a logic bug. And if it does have a bug, there's usually not much that you can do except abort because you can't trust the program anymore.

On the other hand, if you know that your input might be OOB without violating a precondition, as a part of the normal execution of the program, and you can handle it gracefully, use `get` instead.

This distinction between "expected" and "unexpected" errors is an extremely valuable one, and one unnecessarily muddled by languages where all errors are signaled with exceptions. Rust gets it right.

1 comments

I don't understand, tbh. Eg does Rust not make great effort to prevent null pointer exceptions? OOB feels quite similar to null pointer.

It's strange to me because a lot of what I value in Rust is writing code that handles all outcomes safely and with confidence. Yet that all seems to be out the window if you access array values - as it may or may not work.

The safety of [] slice/array access is entirely up to how the dev wrote the code.. which largely feels the same as any other language.

Am I thinking about something incorrectly?

The usage pattern is somewhat different. The primary problem with null references in languages such as Java is that they are not opt-in, and they're not even opt-out! That is to say, you don't even have an option (heh!) to encode in the type system the fact that a reference is never null. What's worse, references tend to get passed around a lot, and stored inside objects, and programmers are lazy and don't assert or even think about preconditions, so the root cause of an unexpected NPE can be far removed from the code that finally triggers it.

With code that indexes slices, the index computation is usually much more proximate to the actual indexing operation. If ensuring the validity of the index is about upholding an invariant internal to the module, it makes no sense to return an "sorry, I have a bug" error to the caller if that invariant fails to hold. What would the caller do about that?

I think the slightly odd or inconsistent thing is that rust has [] at all. I think of it as a compromise for people's familiarity with the operator. And if that's all it is, it makes sense that it behaves the way it does; I think a panic is more similar to what other languages with that operator do with an out of bound index than returning Option would be.