Skip to content

Bikeshedding the 'gen' keyword & syntax #123731

Closed
@dhardy

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.

From the RFC:

@yoshuawuyts For the FCP I started above, the gen keyword and gen { ...} blocks and async gen { ... } blocks are in-scope, while gen 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.

From @Kray:

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 know async fn works the same way, but at least when you see an async fn foo() -> u32 you know it will eventually return a single u32.

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 { ... }

From @withoutboats:

(NOT A CONTRIBUTION)

I think there are several good arguments for replacing -> with something like yield or yields. 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 toward yields; not sure if gen yield i32 could be supported by the parser or if its ambiguous.

From @emilyyyylime:

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.

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.F-gen_blocks`gen {}` expressions that produce `Iterator`sT-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions