Michael-F-Bryan / adventures.michaelfbryan.com

A simple blog for documenting my thoughts and adventures
http://adventures.michaelfbryan.com/
15 stars 3 forks source link

A few minor thoughts on the iterators post #49

Closed scottmcm closed 3 years ago

scottmcm commented 3 years ago

Great post! I had a few minor comments, none of which are really problems, but here they are:

1) Consider IntoIterator::into_iter(0..5) instead of (0..5).into_iter(). It's minor, but emphasizes that it has to be the trait, not an inherent method nor something reachable via auto(de)ref.

2) I love the use of ? in next to handle the ending condition. There's a subtle beauty to it.

3) There are a few reasons the pointer version is good:

Michael-F-Bryan commented 3 years ago

Consider IntoIterator::into_iter(0..5) instead of (0..5).into_iter(). It's minor, but emphasizes that it has to be the trait, not an inherent method nor something reachable via auto(de)ref.

That's definitely the more correct version but I deliberately opted to use method syntax with a later note about IntoIterator because it's easier for a newbie to understand (lies to children and all that).

Chances are if you understand how autoref works you will recognise that we explicitly require an IntoIterator implementation (instead of ducktyping) because of the error messages coming from rustc.

It's more like how C++ does slice iterators

That's actually where I got the inspiration from!

I like it because it makes next() and next_back() very easy to implement and it is easy for me to visualise - you just imagine a strip of cells where your index fingers point at the start and end of the section you care about, then popping from the front/back is just a case of moving a finger inwards until they touch.

My main concern is that the version with start and end pointers will fall over when it comes to zero-sized types and treat all slices as empty. I'm not a big fan of how std hijacks the end pointer to be ptr+len because it litters the code with if mem::size_of::<T>() == 0 and treats a pointer as an integer, but it's probably the best we can do without having some sort of where mem::size_of::<T>() == 0 specialisation using const generics on slice's IntoIterator impl.

scottmcm commented 3 years ago

Yeah, ZSTs definitely make everything a mess.

Slice iterators are definitely a special case for so many things, though. They're so core to everything that they include a bunch of tiny little things (like https://github.com/rust-lang/rust/pull/61885) that would never make sense in "normal" code.