Description
#117078 lists "unresolved" questions:
- Whether we should use some keyword other than gen.
- Whether we should reserve gen as a full keyword or as a contextual one.
@yoshuawuyts For the FCP I started above, the
gen
keyword andgen { ...}
blocks andasync gen { ... }
blocks are in-scope, whilegen fn
is out of scope.
So we need a keyword for "gen blocks"; gen fn
might get added in the future.
Conflicts
This conflicts with rand::Rng::gen
(see rust-random/rand#1435). There are quite a few hits within the rand
crate. The rand_distr
crate has 3 uses within documentation, 2 within tests and 14 in algorithms.
This isn't a lot of data, but hints at quite a few real uses of Rng::gen
outside rand
, not counting other possible uses of gen
.
From the RFC
I haven't read all comments on the RFC, but several indicate that gen fn
may not be a good thing.
IMO this function syntax, while analogous to how async functions work, looks very surprising and non-obvious:
gen fn odd_dup(values: impl Iterator<Item = u32>) -> u32
Without inspecting the opposite end of the line, the function looks like it returns a single
u32
. I knowasync fn
works the same way, but at least when you see anasync fn foo() -> u32
you know it will eventually return a singleu32
.Not to mention there's good arguments why
async fn
might have also been a mistake.Because the "simple" case of an owned iterator doesn't require complicated type signatures unlike some Futures generated by async fn, wouldn't this be a good time to adopt this function expression syntax suggested many times in the past (including the blog post above)?
fn foo() -> impl Iterator<Item = u32> = gen { ... }
(NOT A CONTRIBUTION)
I think there are several good arguments for replacing
->
with something likeyield
oryields
. I'm pretty much just summarizing here:* Educational: it helps users understand that this yields many times, instead of returning once. It ties the declaration syntax to the different return keyword inside the body. * Forward compatibility: I personally don't think general purpose coroutines should be declared with the same keyword as generators-as-Iterators, but this does leave space for that possibility in the syntax by allowing the syntax to support a separate `->` type declaration.
The only possible difficulty you need to consider is that you want to be forward compatibility with the ability to declare the type yielded by a
gen { }
block. This may lean towardyields
; not sure ifgen yield i32
could be supported by the parser or if its ambiguous.
I was thinking potentially
fn f() gen i32
for 'generates'
There is also discussion on usage of generator
instead and discussion on gen
as a contextual keyword.
Since I'm not fully read-up on the status of this RFC and its implementation, I'll just leave this here with the question of whether gen
will become a keyword.