Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement FromIterator for the unit type #1130
Conversation
huonw
reviewed
May 20, 2015
|
|
||
| Implement the trait `std::iter::FromIterator<()>` for the primitive type `()`. | ||
|
|
||
| The implementation is very short: |
This comment has been minimized.
This comment has been minimized.
huonw
May 20, 2015
Member
I wonder if this should run the iterator, rather than discard it, e.g.
fn from_iter<T>(iter: T) -> () where T: IntoIterator<Item = ()> {
for _ in iter {}
}I also wonder if it could be used as a general purpose discard:
impl<X> FromIterator<X> for () {
fn from_iter<T>(iter: T) -> () where T: IntoIterator<Item = X> {
for _ in iter {}
}
}
This comment has been minimized.
This comment has been minimized.
fenhl
May 20, 2015
Author
Good question. If the exhausting implementation is chosen, the generic version seems strictly better as far as I can tell. It could be used, for example, to collect any iterable of Result<T, E> into a Result<(), E>.
This comment has been minimized.
This comment has been minimized.
Gankro
May 20, 2015
Contributor
I don't think we need another general-purpose discard for iterators.
This comment has been minimized.
This comment has been minimized.
alexcrichton
May 26, 2015
Member
I agree with @huonw that this probably wants to exhaust the iterator at least, and we can always leave the X type parameter (exhausting all kinds of iterators) to a future extension.
fenhl
added some commits
May 20, 2015
This comment has been minimized.
This comment has been minimized.
|
Seeing how iterators are lazy in general, I think This also ties in with the future possibility of other fixed-sized containers: let v: FixedCapVec<X, 4> = iter.collect(); // Expected not to iterate more than 4 times.
let v: OptionLike<X> = iter.collect(); // Expected not to iterate more than 1 times.
let v: () = iter.collect(); // Expected not to iterate more than 0 times. |
This comment has been minimized.
This comment has been minimized.
|
What about find? fn forward_values<T>(src: Receiver<T>, dst: Sender<T>) -> Result<(), SendError<T>> {
src.iter().map(|val| dst.send(val)).find(|v|.is_err()).or(Ok(()))
} |
This comment has been minimized.
This comment has been minimized.
|
@Kimundi I agree with your point. A generic implementation would still be useful. |
This comment has been minimized.
This comment has been minimized.
bluss
commented
May 20, 2015
|
This is better written with and yes, I'd propose moving |
nrc
added
the
T-libs
label
May 21, 2015
This comment has been minimized.
This comment has been minimized.
I think this question right here is actually a serious problem for this proposal. There's valid arguments both ways, and I'm inclined to think that the unclear obvious answer to this means we shouldn't do it at all. As @bluss has said, you can implement this with let value = result::fold(src, (), |_,_| ());It might be worth adding a function |
Gankro
self-assigned this
Jun 5, 2015
This comment has been minimized.
This comment has been minimized.
|
I'd personally find it pretty surprising for I'm also personally a fan of "just write the loop" which is IMO much clearer and easier to maintain than a pile of iterator adaptors. Particularly when you're running the code for the side-effects. |
This comment has been minimized.
This comment has been minimized.
|
Collect ought always to exhaust the iterator; collecting an iterator consumes it. No std impl of |
This comment has been minimized.
This comment has been minimized.
bluss
commented
Jun 6, 2015
|
Consuming an iterator or not doesn't matter: consider passing by-ref iterators, where the owner of the iterator can still access it after collect. Taking iterators by value is just the most universal interface, because it allows us to pass iterators either by value or as When collecting or extending into a fixed size data structure, I've for now chosen to not exhaust the iterator, but instead take only as many elements that fits. |
This comment has been minimized.
This comment has been minimized.
|
I suppose I wouldn't expect a data structure with a fixed len to exhaust the remainder of the iterator, and a |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
|
At first glance that seems like a reasonable argument, except fixed-length data structures in general cannot implement FromIterator at all, because there would be no valid behavior for if the iterator did not have enough elements. Only the degenerate case of a zero-length data structure can do that, which kind of defeats the point of considering () as a fixed-length data structure of length 0. |
This comment has been minimized.
This comment has been minimized.
|
@kballard: For fixed length data structures there is always the option of And fixed capacity structures wouldn't have the this problem at all. |
This comment has been minimized.
This comment has been minimized.
|
This RFC is now entering its final comment period. |
alexcrichton
added
the
final-comment-period
label
Jun 16, 2015
This comment has been minimized.
This comment has been minimized.
ruuda
commented
Jun 18, 2015
|
The special-case implementation for |
This comment has been minimized.
This comment has been minimized.
|
I'm not sure a non-lazy behavior is the right choice here. In the future we might want to implement lazy |
This comment has been minimized.
This comment has been minimized.
|
It seems like there's no agreement on what the behaviour of this code should be. It's not clear to me that it can be agreed on. As such I'd suggest not going forward with this RFC, to avoid constant surprise over this behaviour. |
This comment has been minimized.
This comment has been minimized.
|
I agree with Gankro here. If it's lazy, that seems to contradict the motivation of the RFC, if it's strict, then it's inconsistent with the general behaviour of iterators. Since both interpretations are equally intuitive, I can see this being a source of confusion going forwards. |
This comment has been minimized.
This comment has been minimized.
|
The consensus of the libs team is to not merge this RFC at this time, so I'm going to close this. Thanks regardless for the RFC though @fenhl! |
alexcrichton
closed this
Jul 1, 2015
fenhl
deleted the
fenhl:unit-from-iterator
branch
Jul 1, 2015
fenhl
restored the
fenhl:unit-from-iterator
branch
Jul 1, 2015
This comment has been minimized.
This comment has been minimized.
|
The exhausting implementation of this ended up getting implemented in rust-lang/rust#45379. |
fenhl commentedMay 20, 2015
Implement
FromIterator<()>for the empty tuple type()aka unit, allowingResult::from_iterto be used withResult<(), E>.Rendered