Skip to content

Std::iter::once#771

Merged
aturon merged 3 commits into
rust-lang:masterfrom
XMPPwocky:std_iter_once
Apr 15, 2015
Merged

Std::iter::once#771
aturon merged 3 commits into
rust-lang:masterfrom
XMPPwocky:std_iter_once

Conversation

@XMPPwocky

Copy link
Copy Markdown
Contributor

@reem

reem commented Jan 30, 2015

Copy link
Copy Markdown

+1, I've wanted this before and disliked the IMO relatively ugly solutions.

@blaenk

blaenk commented Jan 30, 2015

Copy link
Copy Markdown
Contributor

👍 I think this would be nice. As the RFC states, and as I'm sure droves of people will be tripping over each other to point out, this thing is already possible in a variety of different ways. The point is that this would make the intent clear and its use concise. The most common trick used that I've seen is Some(x).into_iter(), but a dedicated function like once has the benefit of being easy to discover and document, which is useful for newcomers.

@pythonesque

Copy link
Copy Markdown
Contributor

I don't really see what's wrong with the Some(x).into_iter() solution? Other than discoverability, I suppose.

@XMPPwocky

Copy link
Copy Markdown
Contributor Author

@pythonesque Discoverability, ergonomics, and looking strange (coming across it for the first time, it looks odd and you might be tempted to think it's an iterator over Option).

@reem

reem commented Jan 30, 2015

Copy link
Copy Markdown

When someone asks how to do this, Some(x).into_iter() is a trick, iter::once(x) is a solution (even if the implementation is the same).

@Ericson2314

Copy link
Copy Markdown
Contributor

Let's just say I've written //TODO factor out single element iterator a few times :).

@brendanzab

Copy link
Copy Markdown

I made an issue about this before, but was discouraged: #437.

@kmcallister

Copy link
Copy Markdown
Contributor

+1, I had to define this in html5ever to get reasonable APIs.

@drewm1980

Copy link
Copy Markdown

Could you add some examples where this is useful to the RFC? I've done at least some stuff with iterators and have never run into this. It is non-obvious to me why iterators are even relevant if you've only got one thing.

@drewm1980

Copy link
Copy Markdown

bikeshedding on the name, iterators (and only iterators?) yield things. If you want and iterator that yields a value once, how about:

somevalue.yield_once()?

This would fit in more nicely with the language of the other iterator functions:
http://doc.rust-lang.org/1.0.0-alpha/std/iter/index.html

If this is something that will be defined on literally every value in your code, I think you probably want it to be at least a bit specific about what it does, even if it's a few more characters...

@Gankra

Gankra commented Feb 3, 2015

Copy link
Copy Markdown
Contributor

Adding a method on every single value type is unacceptable.

@blaenk

blaenk commented Feb 3, 2015

Copy link
Copy Markdown
Contributor

It is non-obvious to me why iterators are even relevant if you've only got one thing.

@drewm1980: For example, in one of my library's tests I perform a globbing operation to get a list of paths to fixtures, but there's one fixture in a non-standard location (beyond my control), so what I do is I get the iterator for the glob, then I chain onto it the single extra path, so that then I can iterate over the composed iterator as one thing, instead of iterating over the glob, then doing it again only for the extra path that wasn't present in the glob results.

Keep in mind this is just one example of many. Perhaps you have some code that operates on iterators, but you only have one item, so you create an iterator consisting solely of that item.

@brendanzab

Copy link
Copy Markdown

It is non-obvious to me why iterators are even relevant if you've only got one thing.

It is useful when chaining together iterators.

@XMPPwocky

Copy link
Copy Markdown
Contributor Author

This could potentially replace std::iter::repeat with std::iter::once().cycle(); whether that is desirable is undecided.

(You can't replace this with repeat, since repeat needs a Clone bound, while once does not.)

@kmcallister

Copy link
Copy Markdown
Contributor

@drewm1980

It is non-obvious to me why iterators are even relevant if you've only got one thing.

html5ever accepts an iterator of Strings, to support incremental parsing. But this kind of ruins the syntax for the common case of parsing a whole document, if we don't have something like once.

@aturon

aturon commented Feb 3, 2015

Copy link
Copy Markdown
Contributor

+0.5.

While Some(x).into_iter() is usable for this I think it's a natural thing to have alongside other "leaf" combinators like repeat and count. I don't see a lot of downside to growing the API in this way.

(I do suspect that if we add this, we'll want iter::empty or some such as well.)

@drewm1980

Copy link
Copy Markdown

Thanks for the example use cases! RE iterator chaining, don't iterators already chain nicely by design? Are there API's taking iterators of iterators that force you to increase the level of iteratorness in the middle of the chain?

@drewm1980

Copy link
Copy Markdown

Anyway, +1 if it's not in the prelude, or if it's in the prelude with a name that at least hints it's related to iterators, i.e. "yield_once" or something. Is "yield" is already reserved as a keyword, perhaps for future pythonic ways of making generators/closures?

IMHO, "once" alone is too generic for the prelude; at first guess I would expect it to call a closure without using () syntax, like the "twice" example from the docs:

http://doc.rust-lang.org/book/closures.html#accepting-closures-as-arguments

@nikomatsakis

Copy link
Copy Markdown
Contributor

👍 I've wanted this from time to time for certain.

@erickt

erickt commented Feb 20, 2015

Copy link
Copy Markdown

+1 to this and @aturon's iter::empty(). I don't think iter::repeat(x).take(1) works here as it'll only work with Clone types. I don't think we need to have explicit variants for &T and &mut T, we could always just call once(&x) to produce iterators of those types.

@brson

brson commented Feb 20, 2015

Copy link
Copy Markdown
Contributor

lgtm

@steveklabnik

Copy link
Copy Markdown
Contributor

👍

@aturon

aturon commented Feb 20, 2015

Copy link
Copy Markdown
Contributor

We've got a lot of enthusiasm for this RFC, but before we merge, I wonder: is it worth adding empty at the same time? (Seems reasonable to include both variants of the Option iterator.)

@huonw

huonw commented Mar 4, 2015

Copy link
Copy Markdown
Contributor

Do we want the name once & empty? It feels to me that the matching words would be once and never. The mismatch I see now is that once describes how often the element will be yielded, but empty describes the state of the iterator. (A small nitpick...)

@kmcallister

Copy link
Copy Markdown
Contributor

iter::one and iter::none?

@aturon

aturon commented Mar 5, 2015

Copy link
Copy Markdown
Contributor

How about one and empty?

@seanmonstar

Copy link
Copy Markdown
Contributor

One and zero? Or empty seems fine. Problem with one and none is its only 1
char difference...

On Wed, Mar 4, 2015, 9:12 PM Aaron Turon notifications@github.com wrote:

How about one and empty?


Reply to this email directly or view it on GitHub
#771 (comment).

@tshepang

tshepang commented Mar 5, 2015

Copy link
Copy Markdown
Member

@seanmonstar I'd be very surprised to see someone do such a typo. I mean, I didn't even notice they were that close... they look very distinct.

@XMPPwocky

Copy link
Copy Markdown
Contributor Author

@tshepang They'd also have different signatures.

std::iter::one(42);
std::iter::none();

@seanmonstar

Copy link
Copy Markdown
Contributor

Good point, I retract my comment.

On Thu, Mar 5, 2015, 8:20 AM Nathaniel Theis notifications@github.com
wrote:

@tshepang https://github.com/tshepang They'd also have different
signatures.

std::iter::one(42);
std::iter::none();


Reply to this email directly or view it on GitHub
#771 (comment).

@ogham

ogham commented Mar 13, 2015

Copy link
Copy Markdown

I actually found out about the Some(x).into_iter() idiom from this thread just now.

@aturon

aturon commented Mar 17, 2015

Copy link
Copy Markdown
Contributor

@XMPPwocky Can you update the RFC with empty as well? Otherwise, it's ready to be accepted at this point.

@XMPPwocky

Copy link
Copy Markdown
Contributor Author

@aturon Done. Sorry, email from GitHub found its way into the great Gmail tab of spammy mailing lists, for some reason.

@aturon

aturon commented Apr 15, 2015

Copy link
Copy Markdown
Contributor

Thanks @XMPPwocky!

After getting stalled on some bikeshedding and lost emails, this RFC (which always has strong support) has been merged at last!

@Centril Centril added A-types-libstd Proposals & ideas introducing new types to the standard library. A-iterators Iterator related proposals & ideas labels Nov 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-iterators Iterator related proposals & ideas A-types-libstd Proposals & ideas introducing new types to the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.