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

State that the set of ValueTuple types provided is implementation-defined #798

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions standard/portability-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ A conforming implementation is required to document its choice of behavior in ea
1. The behavior of the `fixed` statement if the array expression is `null` or if the array has zero elements ([§23.7](unsafe-code.md#237-the-fixed-statement)).
1. The behavior of the `fixed` statement if the string expression is `null` ([§23.7](unsafe-code.md#237-the-fixed-statement)).
1. The value returned when a stack allocation of size zero is made ([§23.9](unsafe-code.md#239-stack-allocation)).
1. The set of `System.ValueTuple<...>` types available for tuple types ([8.3.11](types.md#8311-tuple-types))

## B.4 Unspecified behavior

Expand Down
2 changes: 1 addition & 1 deletion standard/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ An enumeration type is a distinct type with named constants. Every enumeration t

### 8.3.11 Tuple types

A tuple type represents an ordered, fixed-length sequence of values with optional names and individual types. The number of elements in a tuple type is referred to as its ***arity***. A tuple type is written `(T1 I1, ..., Tn In)` with n ≥ 2, where the identifiers `I1...In` are optional ***tuple element names***. This syntax is shorthand for a type constructed with the types `T1...Tn` from `System.ValueTuple<...>`, which shall be a set of generic struct types capable of expressing tuple types of any arity greater than one.
A tuple type represents an ordered, fixed-length sequence of values with optional names and individual types. The number of elements in a tuple type is referred to as its ***arity***. A tuple type is written `(T1 I1, ..., Tn In)` with n ≥ 2, where the identifiers `I1...In` are optional ***tuple element names***. This syntax is shorthand for a type constructed with the types `T1...Tn` from `System.ValueTuple<...>`, which shall be a set of generic struct types capable of expressing tuple types of any arity greater than one. The precise set of `System.ValueTuple<...>` types provided is implementation-defined.

> *Note*: There does not need to exist a `System.ValueTuple<...>` declaration that directly matches the arity of any tuple type with a corresponding number of type parameters. Instead, larger tuples can be represented with a special overload `System.ValueTuple<..., TRest>` that in addition to tuple elements has a `Rest` field containing a nested tuple value of the remaining elements. Such nesting may be observable in various ways, e.g. via the presence of a `Rest` field. *end note*
Copy link
Contributor

@KalleOlaviNiemitalo KalleOlaviNiemitalo Jun 5, 2023

Choose a reason for hiding this comment

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

Reading this made me worry about possible conflicts in overloaded methods, if one method takes an (int, int, int, int, int, int, int, char, char) parameter and another overload takes (int, int, int, int, int, int, int, (char, char)) -- does the compiler translate both of those to ValueTuple<int, int, int, int, int, int, int, ValueTuple<char, char>>? But no, the latter becomes ValueTuple<int, int, int, int, int, int, int, ValueTuple<ValueTuple<char, char>>> instead. Here, TRest is a ValueTuple<T1> with only one type argument, and does not correspond to any C# tuple type. The wording "a nested tuple value" is a bit misleading, then, as it could be taken to mean an instance of a tuple type.

Perhaps "shall be a set of generic struct types capable of expressing tuple types of any arity greater than one" should also be changed to require ValueTuple<T1>, at least in those implementations that translate large-arity tuple types to System.ValueTuple<..., TRest>. If the implementation does generate a dedicated generic type for tuple types of each arity, instead of using TRest, then I suppose it need not support ValueTuple<T1>, because:

  • The non-generic struct ValueTuple and its public static ValueTuple<T1> Create\<T1>(T1 item1) method is not part of Annex C Standard library.
  • struct ValueTuple<T1> is part of Annex C Standard library, but its omission can be excused because "The precise set of System.ValueTuple<...> types provided is implementation-defined."

Copy link
Contributor

Choose a reason for hiding this comment

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

@KalleOlaviNiemitalo – I see your point but rather than trying to improve the wording I would suggest a different tack.

The C# Standard does not specify a “wire format” for interoperability of binary data, or how arrays should be stored, and a myriad of other things. Why is it specifying how a tuple should be stored? Why even mention ValueTuple? Are these not implementation details of the kind the Standard doesn’t usually cover?

Rather than add a sentence to the end of the paragraph, and the following note, why not delete ”This syntax is shorthand for … arity greater than one” instead?


Expand Down