Include `collect_vec` in `std`?

I use .collect::<Vec<_>>() quite often (probably mostly in tests). I know about Itertools::collect_vec but have never needed anything else from this crate.

Would it make sense to add collect_vec to std::iter::Iterator?

(I guess this would be a breaking change for users of Itertools, but not a breaking change in std itself.)

11 Likes

I think this would be a nice convenience, but we'd want/need to do it in a way that doesn't blow up itertools users. One simple option there is a different name like .to_vec().

4 Likes

A shorter name is good because it's used often enough.

I like this better but it should be into_vec to follow the naming conventions

12 Likes

I like this too. It’s a very common thing that I type, especially in tests.

1 Like

This is a general problem with itertools, because it contains some other things we'll want in std. How to face this problem better?

++

I think going through crates.io and looking at what the most popular itertools calls are might be a good idea.

2 Likes

Generally speaking; I think the solution going forward is to make PRs for the standard library first and only to itertools if it can't be in the standard library or T-libs doesn't want it.

I recently got a PR to itertools regarding this merged: README.md: Clarify policy wrt. contribution and standard library by Centril · Pull Request #294 · rust-itertools/itertools · GitHub

Yes please!

Do name it to_vec though: itertools useses wordy collect specifically to avoid conflict with more appropriate to_vec.

My rational for this:

  • it helps with type inference: compiler gives better error messages, IDE can give sane completions even if the following code is not written yet, human can read function top-down to infer the types.

  • it helps with more fluent coding: collect + turbofish is a lot of symbols!

  • it uses less power, which is good. Return type polymorphism is one of the greatest features of rust, but if you don’t use it in generic context, then it is just an unnecessary complication.

3 Likes

This would consume the iterator, so shouldn’t it be into_vec?

8 Likes

Yes, it should be called into_vec. :wink:

9 Likes

Alternatively (and I think it’s been mentioned before), could .collect() have a default type it collects to?

3 Likes

+1 in the name of paving the cow paths.

1 Like

Method type parameters can’t have defaults.

Could they be made to have defaults?

2 Likes

Even if it could, Iterator is in core where the Vec type doesn’t exist yet.

Actually, this seems to be a problem for the entire thread here, no?

6 Likes

Yeah, it’d have to be a separate trait with a blanket impl in std.

1 Like

There was an RFC: https://github.com/rust-lang/rfcs/pull/2321

1 Like

I’ve done this a lot too, but often with the Vec wrapped in Result. I often want to run things through iterators as the ability to chain gives me great flexibility, but have to bleed off the errors somehow.

Personally I find I never need to use turbofish for collecting data. I use collect() when either I need to return a regular collection (e.g. a Vec) rather than an Iterator, and otherwise only when I need to get a regular collection as a local (this one is increasingly rare).

In the first use case, I just to .collect() and let type inference take care of the rest. The latter mostly used to happen before impl Trait became stable, and then only when I couldn’t chain methods on the Iterator any further e.g. because I needed to pass an owned collection of the iterated items.

So mostly I’m just wondering: What makes you use the turbofish when using .collect()?