Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yeah, in Rust it’d fall very neatly out of the type system, as `input.get(i - 1).unwrap_or(0) + input.get(i + 1).unwrap_or(0)`.


Funnily enough, that Rust code is actually buggy, because i is a usize and if i == 0 then i-1 will panic due to underflow. You'd have to write

  input.get(i.wrapping_sub(1)).unwrap_or(0) + input.get(i+1).unwrap_or(0)
This also technically won't work right if the slice has usize::MAX elements, but that's rather unlikely.

This is one area where Swift's choice of using signed Int for most things actually works quite well. The equivalent Swift code would be something like

  (input[safe: i-1] ?? 0) + (input[safe: i+1] ?? 0)
though unfortunately Swift doesn't ship with Array.subscript(safe:) so you have to write that yourself.


A slice of a non-ZST element cannot have `usize::MAX` elements, by definition of `usize`.


Slices of ZST elements is indeed what I was thinking of, but is there anything actually stopping me from constructing a `std::slice::from_raw_parts(0 as *const u8, usize::MAX)`? What if I'm working on an architecture where the heap and stack are separate address spaces, and every single address in the heap is reachable? In fact, doesn't WebAssembly work this way? If I can declare that my linear memory is usize::MAX bytes, then constructing a slice that covers the entire memory address seems like a potentially-valid thing to do.


> i is a usize and if i == 0 then i-1 will panic due to underflow.

Not in release mode.


While it's true that it doesn't panic in release mode, that's supposed to be an optimization and the correct semantics are what's implemented in debug mode. Besides, you don't want to write a program that only functions in release mode.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: