Rethink `__dunder__` methods for discoverability and developer experience

You seem to dislike “getitem” in particular.
I have an idea for making it safer while preserving the ergonomics of subscripting.
Then, a feature like explicit raises could be added to enforce stricter error handling, either as a language feature or a compiler flag.

For reference: Proposal: Introduce implicit raises for Optional Error Handling

fn append(mut self, value: T) implicit raises OutOfMemoryError: ... 
fn __add__(lhs: Self, rhs: Self) implicit raises OverflowError -> Self: ...
fn __getitem__(self, index: Int) implicit raises IndexError -> T: ...