Skip to content

Bikeshedding the 'gen' keyword & syntax #123731

Description

@dhardy

#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.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions