That said, one of the places Rust loses people pretty early on is an example they have early in this intro:
```rust
let parts: Vec<&str> = "a,b,c".split(',').collect(); // Vec<&str>
```
I never understood why Rust didn't / couldn't make functions able to return different outputs depending on context. If you chain `.split()` to something else that can take an iterator, you want to pass an iterator. If you don't, ~99% of people would probably rather have a collected array. And if you want an `it`, you could just do `.it()` or this is when type inference could be overloaded and you could do:
```rust
let it: Split<'_, char> = "a,b,c".split(',');
```
I think Rust should've put more effort into making the thing newbs want to do the default, and easy ways to get the most efficient thing for experts.
```rust
let parts = "a,b,c".split(); // Gives an Array/Vec
let count = "a,b,c".split().count(); // Optimized stream, no array allocation
```
It could work like that, and I think almost everyone would be happy. But it doesn't.
Instead, they've created a language that I think could have been nearly as easy as a scripting language, but isn't.
It obviously isn't only collection iterators this applies to. There's dozens of very small places that add up and make what - I believe - is an otherwise relatively easy and sensible language feel too far out of reach for too many people.
`Option<T>`, `Result<T, E>`, `Future<T>` all impact linguistically how you can interact with a Type. I think the impacts of this don't make sense to people who've never encountered this before. `Arc<T>`, `Rc<T>`, `Mutex<T>`, and `RwLock<T>`, etc also have similar consequences.
Not only do people just not get it. But also, the type system quickly becomes "scary". To do pretty basic concurrency, you need to build a pretty "scary" looking type if you come from Python.
Which is why I'm a psychopath and attempting to create a language where it defaults to the things most people want, and it's very easy for experts to override.