Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C# 7.x: Unifying treatment of discards and local variables in patterns, deconstruction and out variables #561

Closed
MadsTorgersen opened this issue Apr 28, 2022 · 5 comments
Assignees
Labels
status: in-progress The assignee has actively started working on this; consult with them before taking other actions type: feature This issue describes a new feature
Milestone

Comments

@MadsTorgersen
Copy link
Contributor

Pattern, deconstruction expressions and out variables all allow for local variables to be declared in places that are not accounted for by existing scope rules. In addition, those locations allow for the use of discards in lieu of existing or fresh variables.

Currently the treatment of these variables is spread out and partially duplicated across #61, #63 and #44. I think there's both an opportunity and a need for unifying this treatment, quite possibly introducing new concepts/terms in the process.

Perhaps the best approach is to treat this as a separate "feature" with its own PR, which the above PRs can then build on. The "feature" introduces new concepts (e.g. discards), scope rules etc. but does not in and of itself surface them in syntax.

@MadsTorgersen MadsTorgersen added the type: feature This issue describes a new feature label Apr 28, 2022
@MadsTorgersen MadsTorgersen added this to the C# 7.x milestone Apr 28, 2022
@MadsTorgersen MadsTorgersen self-assigned this Apr 28, 2022
@RexJaeschke RexJaeschke self-assigned this Jun 17, 2022
@RexJaeschke RexJaeschke added the status: in-progress The assignee has actively started working on this; consult with them before taking other actions label Jun 17, 2022
@RexJaeschke
Copy link
Contributor

As Mads is otherwise occupied for a while, and I have the time, I’ve been working on this issue.

I’m starting with discards, and then will look at local variable declarations.

Thus far

  • I’ve created (but not yet posted) draft text for a new PR that introduces discards.
  • I’ve figured out the changes needed for PR #44 (out variables) to point to that new PR, and I’ve found (unrelated) enhancements and corrections for PR 44.

Next, I need to

  • Reconcile PR #61 (patterns) with the new discard PR, tweaking the discard PR, as necessary.
  • Reconcile PR #63 (tuples) with the new discard PR, tweaking the discard PR, as necessary.

My thinking is to then

  • Create the new discard PR and add commits to the 3 existing PRs for any discard-related edits.
  • Figure out how to unify the declaration of local variables in out variable arguments, patterns, and tuples, with existing local-variable usage.
  • Add commits to the 3 existing PRs for any local-variable-related edits.

@RexJaeschke
Copy link
Contributor

I've created PR 596 to add discards as a separate feature.

I've revised PR 44, as follows:

  • removed discard spec text
  • removed handling of discards on lhs of simple assignment
  • replaced uses of variable_reference with identifier to accommodate discards as well as variable names
  • simplified and expanded the out-argument examples

@RexJaeschke
Copy link
Contributor

I've completed the discard spec part. After looking at the local-variable-creation aspect, I have the following to report:

[The use of not_ indicates "any identifier except _".]

Out Variable

Type is optional

argument_value
   : 'out' local_variable_type? identifier
   ;

local_variable_type
    : type
    | 'var'
    ;

If type/var is present, _ is a typed discard; not_ is a new local variable, provided none by that name already exists (which is an error).

If type/var is absent, _ is an existing local variable if one by that name is in-scope; otherwise, _ is an untyped discard. Either way, not_ must be an existing local variable.

Pattern

Type is required

declaration_pattern
 : type identifier
 ;

var_pattern
: 'var' identifier
;

_ is a typed discard; not_ is a new local variable. identifier is never bound to an existing local variable.

Tuple Deconstruction

Type is optional

destination
 : local_variable_type? identifier
 ;

If type/var is present, _ is a typed discard; not_ is a new local variable, provided none by that name already exists (which is an error).

If type/var is absent, _ is an existing local variable if one by that name is in-scope; otherwise, _ is an untyped discard. Either way, not_ must be an existing local variable.

Commentary

As shown in the descriptions above, the “out variable” and “tuple deconstruction” cases have equivalent syntax and the same semantics, but the “pattern” case is different.

The syntax for local variables is defined in §12.6, “Local variable declarations.” However, that context also allows for the declaration of multiple identifiers as well as initializers, things not allowed in the cases above. And in §12.9.5, “The foreach statement,” we also have custom prose, as only one identifier and no initializer is allowed there. As such, I don’t see any opportunities to leverage further on existing uses of local variable declarations.

@MadsTorgersen, are you able to take ownership of this again?

@MadsTorgersen
Copy link
Contributor Author

Thanks so much for the work you've done on this, @RexJaeschke! I've blocked time on my calendar to try to bring it all together before the November meeting.

@BillWagner
Copy link
Member

Fixed in #664

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: in-progress The assignee has actively started working on this; consult with them before taking other actions type: feature This issue describes a new feature
Projects
None yet
Development

No branches or pull requests

3 participants