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

Create general by-reference clause #1028

Merged

Conversation

BillWagner
Copy link
Member

@BillWagner BillWagner commented Dec 11, 2023

Fixes #799

There are several declarations that are duplicated, or triplicated in the description of in, out, and ref parameters.

This PR pushes those into a common section on "by-reference parameters". Each subsequent section describes the particular keyword.

The diffs are less helpful than I'd hoped, so I've annotated the changes to make reviews easier.

Fixes dotnet#799

There are several declarations that are duplicated, or triplicated in the description of `in`, `out`, and `ref` parameters.

This PR pushes those into a common section on "by-reference parameters". Each subsequent section describes the particular keyword.
@BillWagner BillWagner added the meeting: discuss This issue should be discussed at the next TC49-TG2 meeting label Dec 11, 2023
Copy link
Member Author

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding comments for reviewers because the diffs aren't as useful as I'd hoped.


When a formal parameter is an input parameter, the corresponding argument in a method invocation shall consist of either the keyword `in` followed by a *variable_reference* ([§9.2.8](variables.md#928-input-parameters)) of the same type as the formal parameter, or an *expression* for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from that argument expression to the type of the corresponding parameter. A variable shall be definitely assigned before it can be passed as an input parameter.
> *Note*: The referent of a by-reference parameter can be changed using the ref assignment (`= ref`) operator.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note was only in the in and ref sections. However, it applies to out parameters as well.

It is a compile-time error to modify the value of an input parameter.

Within a method, an input parameter is always considered definitely assigned.
When a formal parameter is a by-reference parameter, the corresponding argument in a method invocation shall consist of the corresponding keyword, `in`, `ref`, or `out`, followed by a *variable_reference* ([§9.5](variables.md#95-variable-references)) of the same type as the formal parameter. However, when the formal parameter is an `in` parameter, the argument may be an *expression* for which an implicit conversion ([§10.2](conversions.md#102-implicit-conversions)) exists from that argument expression to the type of the corresponding parameter.
Copy link
Member Author

@BillWagner BillWagner Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph was almost identical in all sub-clauses. I propose this edit, where the exception for in is declared in the general clause. An alternative would be to keep the (almost) triplicate code in each of the three sub-clauses.

In a method that takes input parameters, it is possible for multiple names to represent the same storage location.

> *Note*: The primary purpose of input parameters is for efficiency. When the type of a method parameter is a large struct (in terms of memory requirements), it is useful to be able to avoid copying the whole value of the argument when calling the method. Input parameters allow methods to refer to existing values in memory, while providing protection against unwanted changes to those values. *end note*
In a method that takes multiple by-reference parameters, it is possible for multiple names to represent the same storage location.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was interesting. The original text disallowed in on iterators and async methods. For ref, only iterators were disallowed (incorrect: ref is disallowed for async). For out parameters, it was only disallowed for iterators and partial methods. The statement on partial methods is now in the section for out, and the other restrictions are here.

A method declared as a partial method ([§15.6.9](classes.md#1569-partial-methods)) or an iterator ([§15.14](classes.md#1514-iterators)) may not have output parameters.

Output parameters are typically used in methods that produce multiple return values.
> *Note: Output parameters are typically used in methods that produce multiple return values. *end note*
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was normative in the existing draft. I don't think it's required to be normative, so I made this a note.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, anything with "typically" shouldn't be normative.


A parameter declared with a `ref` modifier is a reference parameter. A reference parameter is a local reference variable ([§9.7](variables.md#97-reference-variables-and-returns)) that gets its initial referent from the corresponding argument supplied in the method invocation.
A parameter declared with an `in` modifier is a input parameter. The argument corresponding to an `in` parameter is either a variable existing at the point of the method invocation, or one created by the implementation ([§12.6.2.3](expressions.md#12623-run-time-evaluation-of-argument-lists)) in the method invocation. A variable shall be definitely assigned before it can be passed as an input parameter. Within a method, an input parameter is always considered definitely assigned.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rules on definite assignments have the "2 out of 3" problem. The rules for in and ref are identical: The variable representing the argument must be definitely assigned before using it as an argument, and the parameter is considered definitely assigned in the entirety of the method. The rules for out are different. Here, I chose to keep the three distinct copies. I think it read better.

Copy link
Contributor

@jskeet jskeet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked at the new text more than the change (as you noted the diffs weren't helpful). A couple of suggestions, but otherwise looks good as a reconciliation.

Would be good to get feedback from others as well though.

A method declared as a partial method ([§15.6.9](classes.md#1569-partial-methods)) or an iterator ([§15.14](classes.md#1514-iterators)) may not have output parameters.

Output parameters are typically used in methods that produce multiple return values.
> *Note: Output parameters are typically used in methods that produce multiple return values. *end note*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, anything with "typically" shouldn't be normative.

BillWagner and others added 2 commits December 21, 2023 11:42
Co-authored-by: Jon Skeet <skeet@pobox.com>
Co-authored-by: Jon Skeet <skeet@pobox.com>
@BillWagner BillWagner merged commit a859ac4 into dotnet:draft-v8 Feb 7, 2024
7 checks passed
@BillWagner BillWagner deleted the de-triplicate-reference-parameters branch February 7, 2024 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meeting: discuss This issue should be discussed at the next TC49-TG2 meeting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

De-triplicate input, output, and reference parameters.
2 participants