-
Notifications
You must be signed in to change notification settings - Fork 93
Add support for Index & Range #1369
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
base: draft-v8
Are you sure you want to change the base?
Conversation
Editorial NitsI can take care of the following once we merge this PR:
|
In email Nigel sent to active TG2 members on 2025-07-12, Subject: [TG2] Re: PR#1369 Add support for Index & Range, he wrote
I've generalized that question by linking (the currently Parked) Issue 1135 to here, and asked for priority on that Issue next call. |
Thanks for quick the review, I'll work my way down.
Will be in next commit.
This one beat my spell-checker, will be in the commit.
Not sure about this one. While “chapter” does not occur in the text often (I think it is used a few times in 3 out of 7 versions) when it does it is referring to a whole §N (no .M), i.e. a whole chapter ;-) Further it is used in the page headings in most versions including the last one, v7. I like that it unambiguously refers to the whole chapter. We typically use “subclause” (which GitHub has now replaced twice with “subclass” and I've fixed it, I may not spot this every time!) for a §N(.M)+, but not always, sometimes I think to refer to a chapter, and sometimes to refer to a language construct – some examples:
I can see an argument for “chapter”, a review of how (sub)clause is used (yikes!), and acknowledge the usages I added are currently the only ones in v8.
These two are definitely more @RexJaeschke’s area than mine, I happily leave them to him, thanks :-) |
Re chapter/clause usage. Until we adopted the wrapper spec for ISO to avoid complying completely with their style, we followed ISO rules in this regard. And we might as well keep doing that to be consistent.
|
Isn't it also a requirement that all text is in subclauses (the reason for all the §N.1 General subclauses)? So a clause has no text in it and something like “see clause §N“ can be taken to mean the whole clause and all the subclauses, i.e. what “chapter” has been used for occasionally over the versions and now in this PR. Does this mean something like “see clause §N.M” should use subclause, or does the “.M” allow clause to be used? Anyway, if this is definitive we need an issue to remove “Chapter” from the page headers in the final Standard (where it is in most ECMA releases). I suspect that clause might be misused to mean subclause, and that it is not maybe clear that clause means the whole chapter, so so cleanup might be in order. There are 107 uses (in draft-v8 at the point this PR branched), I think most refer to language clauses so are fine so the job isn’t too daunting… |
Yes, Any clause or subclause containing a subclause cannot have its own text. Specifically, "hanging paragraphs are not allowed."
Exactly! This is the reason ISO has this requirement. A reference of §N always means all of N and its subordinates, and a reference of §N.M always means all of N.M and its subordinates.
N.M is a subclause, not a clause. ISO only uses the word "Clause" in a reference when the whole clause is intended. They do not use "subclause" for N.M, but rather, say nothing, so "see §N.M" is used instead. That said, ISO does not allow the use § in references, but I've always has it in documentation I've written, and I introduced it in V1.
Good observation. When we are ready to push out a new edition, Jon gives me the final generated Word version and I do light formatting on it before submitting it to Ecma. I just added to my list of "things to do in that process" to change the clause headers from "Chapter" to "Clause." Or we could simply omit that word altogether. In any event, we don't say "Annex" for each Annex header.
Once we've discussed this I can clean this up. |
@RexJaeschke wrote:
Well of course they don’t, it is the section sign and they are clearly anti-section ;-), we like §, M§GA (ducking) ;-) Are there enough ;-)’s? With the plan to remove all the occurrences of chapter and aim for consistency on the use of (sub)clause, the need for things like “this subclause and its subclauses”, et al., the four that are down to me will be gone in the next commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots of tiny nits/typos, but I'm generally liking the approach here a lot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very impressive PR! I read through everything in the standard folder, and as far as I can see, the whole thing checks out.
@@ -784,6 +784,10 @@ | |||
- [§23.8.3](unsafe-code.md#2383-fixed-size-buffers-in-expressions) Fixed-size buffers in expressions | |||
- [§23.8.4](unsafe-code.md#2384-definite-assignment-checking) Definite assignment checking | |||
- [§23.9](unsafe-code.md#239-stack-allocation) Stack allocation | |||
- [§24](ranges.md#24-ranges-and-slicing) Ranges and Slicing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- [§24](ranges.md#24-ranges-and-slicing) Ranges and Slicing | |
- [§24](ranges.md#24-ranges-and-slicing) Extended indexing and slicing |
@@ -0,0 +1,309 @@ | |||
# 24 Extended Indexing and Slicing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 24 Extended Indexing and Slicing | |
# 24 Extended indexing and slicing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm mildly amused that the name of the file doesn't occur anywhere within its title. How much do we care?
@@ -112,7 +112,9 @@ Elements of arrays created by *array_creation_expression*s are always initialize | |||
|
|||
## 17.4 Array element access | |||
|
|||
Array elements are accessed using *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array element access is a variable, namely the array element selected by the indices. | |||
Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. | |
Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference ([§9.5](variables.md#95-variable-references)) to the array element selected by the indices. |
Array elements are accessed using *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array element access is a variable, namely the array element selected by the indices. | ||
Array elements are accessed using the *array access* variant of *element_access* expressions ([§12.8.12.2](expressions.md#128122-array-access)) of the form `A[I₁, I₂, ..., Iₓ]`, where `A` is an expression of an array type and each `Iₑ` is an expression of type `int`, `uint`, `long`, `ulong`, or can be implicitly converted to one or more of these types. The result of an array access is a variable reference (§9.5) to the array element selected by the indices. | ||
|
||
Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to it, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to it, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. | |
Array elements of single-dimensional arrays can also be accessed using an array access expression where the sole index, `I₁`, is an expression of type `Index`, `Range`, or can be implicitly converted to one or both of these types. If `I₁` is of type `Index`, or has been implicitly converted to that type, then the result of the array access is a variable reference to the array element selected by the index value. If `I₁` is of type `Range`, or has been implicitly converted to that type, then the result of the element access is a new array formed from a shallow copy of the array elements with indices in the `Range`, maintaining the element order. |
<!-- markdownlint-disable MD028 --> | ||
|
||
<!-- markdownlint-enable MD028 --> | ||
> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* | |
> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses ([§12.8.12.3](expressions.md#128123-indexer-access)) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* |
> > > *Note:* A range of elements of an array cannot be assigned to using an array access. This differs from indexer accesses (§12.8.12.3) which may, but need not, support assignment to a range of indices specified by a `Range` value. *end note* | ||
|
||
- Otherwise: | ||
- The result of evaluating the array access is a variable reference (§9.5) of the element type of the array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The result of evaluating the array access is a variable reference (§9.5) of the element type of the array. | |
- The result of evaluating the array access is a variable reference ([§9.5](variables.md#95-variable-references)) of the element type of the array. |
|
||
#### §string-access String access | ||
|
||
For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument (§15.6.2.2) which shall be: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument (§15.6.2.2) which shall be: | |
For a string access the *argument_list* of the *element_access* shall contain a single unnamed value argument ([§15.6.2.2](classes.md#15622-value-parameters)) which shall be: |
new Index(x, true) | ||
``` | ||
|
||
As with the other *unary_expression*s the operand may have a compile-time type of `dynamic` (§12.9.1) and be dynamically bound (§12.3.3). The compile-time type of the result is always `Index`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the other *unary_expression*s the operand may have a compile-time type of `dynamic` (§12.9.1) and be dynamically bound (§12.3.3). The compile-time type of the result is always `Index`. | |
As with the other *unary_expression*s the operand may have a compile-time type of `dynamic` ([§12.9.1](expressions.md#1291-general)) and be dynamically bound ([§12.3.3](expressions.md#1233-dynamic-binding)). The compile-time type of the result is always `Index`. |
Range operator ..(Index x, Index y); | ||
``` | ||
|
||
The range operator is not overloadable (§12.4.3). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The range operator is not overloadable (§12.4.3). | |
The range operator is not overloadable ([§12.4.3](expressions.md#1243-operator-overloading)). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tool will add this automatically.
|
||
A lifted ([§12.4.8](expressions.md#1248-lifted-operators)) form of the range operator is also predefined. | ||
|
||
The range operator is non-associative (§12.4.2). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The range operator is non-associative (§12.4.2). | |
The range operator is non-associative ([§12.4.2](expressions.md#1242-operator-precedence-and-associativity)). |
|
||
> *Note*: The model does not require that a slice, unlike an element, of the type can be set, but a type may support it as an extension of the model. *end note* | ||
|
||
The model is supported for single-dimensional arrays (§12.8.12.2) and strings (§string-access). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The model is supported for single-dimensional arrays (§12.8.12.2) and strings (§string-access). | |
The model is supported for single-dimensional arrays ([§12.8.12.2](expressions.md#128122-array-access)) and strings (§string-access). |
|
||
The model is supported for single-dimensional arrays (§12.8.12.2) and strings (§string-access). | ||
|
||
The model can be supported by any class, struct or interface type which provides appropriate indexers (§15.9) which implement the model semantics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The model can be supported by any class, struct or interface type which provides appropriate indexers (§15.9) which implement the model semantics. | |
The model can be supported by any class, struct or interface type which provides appropriate indexers ([§15.9](classes.md#159-indexers)) which implement the model semantics. |
|
||
> *Note:* `Index` values are unordered as they are abstract indices, it is in general impossible to determine whether a from-end index comes before or after a from start index without reference to a sequence length. Once converted to concrete indices, e.g. by `GetOffset`, those concrete indices are comparable. *end note* | ||
|
||
`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: | |
`Index` values may be directly used in the *argument_list* of an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) which is: |
|
||
`Index` values may be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: | ||
|
||
- an array access and the target is a single-dimensional array (§12.8.12.2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an array access and the target is a single-dimensional array (§12.8.12.2); | |
- an array access and the target is a single-dimensional array ([§12.8.12.2](expressions.md#128122-array-access)); |
|
||
- an array access and the target is a single-dimensional array (§12.8.12.2); | ||
- a string access (§string-access) | ||
- an indexer access and the target type has an indexer with corresponding parameters of either `Index` type (§12.8.12.3) or of a type to which `Index` values are implicitly convertible; or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an indexer access and the target type has an indexer with corresponding parameters of either `Index` type (§12.8.12.3) or of a type to which `Index` values are implicitly convertible; or | |
- an indexer access and the target type has an indexer with corresponding parameters of either `Index` type ([§12.8.12.3](expressions.md#128123-indexer-access)) or of a type to which `Index` values are implicitly convertible; or |
|
||
> *Note:* `Range` values are unordered both as they are abstract and there is no unique ordering relation. Once converted to a concrete start and length, e.g. by `GetOffsetAndLength`, an ordering relation could be defined. *end note* | ||
|
||
`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: | |
`Range` values can be directly used in the *argument_list* of an *element_access* expression ([§12.8.12.2](expressions.md#128122-array-access)) which is: |
|
||
`Range` values can be directly used in the *argument_list* of an *element_access* expression (§12.8.12) which is: | ||
|
||
- an array access and the target is a single-dimensional array (§12.8.12.2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an array access and the target is a single-dimensional array (§12.8.12.2); | |
- an array access and the target is a single-dimensional array ([§12.8.12.2](expressions.md#128122-array-access)); |
|
||
If an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: | ||
|
||
- an array access (§12.8.12.2), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an array access (§12.8.12.2), | |
- an array access ([§12.8.12.2](expressions.md#128122-array-access)), |
|
||
### 24.4.1 General | ||
|
||
If an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: | |
If an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Index` or `Range`; fails to be identified as: |
- an array access and the target is a single-dimensional array (§12.8.12.2); | ||
- a string access (§string-access); | ||
- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type (§12.8.12.3) or of a type to which `Range` values are implicitly convertible; or | ||
- an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an indexer access (§12.8.12.3) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). | |
- an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)) and the target type conforms to a sequence pattern for which implicit `Range` support is specified (§24.4.3). |
|
||
- an array access and the target is a single-dimensional array (§12.8.12.2); | ||
- a string access (§string-access); | ||
- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type (§12.8.12.3) or of a type to which `Range` values are implicitly convertible; or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type (§12.8.12.3) or of a type to which `Range` values are implicitly convertible; or | |
- an indexer access and the target type has an indexer with corresponding parameters of either `Range` type ([§??](???)) or of a type to which `Range` values are implicitly convertible; or |
|
||
- an array access (§12.8.12.2), | ||
- a string access (§string-access), or | ||
- an indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- an indexer access (§12.8.12.3) as `T` provides no suitable accessible indexer | |
- an indexer access ([§12.8.12.3](expressions.md#128123-indexer-access)) as `T` provides no suitable accessible indexer |
|
||
### 24.4.3 Implicit Range support | ||
|
||
If in any context an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If in any context an *element_access* expression (§12.8.12) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: | |
If in any context an *element_access* expression ([§12.8.12](expressions.md#12812-element-access)) of the form `E[A]`; where `E` has type `T` and `A` is a single expression implicitly convertible to `Range`; is not valid (§24.4.1) then if in the same context: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ready to approve this. This is great workk.
There are some discussion items for our meeting to resolve though.
- The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). | ||
- The result of the string access is a new string formed by copying the *N* characters of `P` starting from *S*, if *N* is zero the new string is empty. | ||
|
||
> > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty string returned. *end note* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we've consistently used this form, which might be easier for the Word Converter:
> > > *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty string returned. *end note* | |
> *Note:* Both *S* and *N* may be zero (§24.3). Indexing an empty string is usually invalid, however indexing with an empty range starting at zero is valid and returns an empty string. The defintion also allows *S* to be *L*, the past-end index (§24.1), in which case *N* will be zero and an empty string returned. *end note* |
### §hat-operator Hat operator | ||
|
||
The unary `^` operator is called the *hat* operator. The hat operator is not overloadable (§12.4.3) and there is a single predefined hat operator: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not thrilled with "hat operator". While I'm not sold on any of these, here are some alternatives:
- "end operator"
- "reverse index operator"
- "from end operator" (I like this one least)
- "tail end operator"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, I like "from end operator" most as it corresponds with Index.FromEnd
. (I could live with "index-from-end operator" as well, to be even clearer...)
Range operator ..(Index x, Index y); | ||
``` | ||
|
||
The range operator is not overloadable (§12.4.3). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tool will add this automatically.
> | ||
> *end note* | ||
|
||
## 24.2 The Index type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should discuss these two sections.
It's great work, but we have steadfastly avoided defining the semantics for library types. I see your point, but I'm concerned about increasing our workload when we are almost 6 releases behind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I'm okay with defining the semantics of just Index and Range themselves, but not the semantics of how they're used.
Is the workload concern in terms of ongoing maintenance beyond the initial definition that has already been provided?
(No need to respond here - let's definitely discuss in the meeting.)
Co-authored-by: Rex Jaeschke <[email protected]>
@@ -1823,7 +1822,7 @@ null_forgiving_operator | |||
; | |||
``` | |||
|
|||
*Note*: The postfix null-forgiving and prefix logical negation operators ([§12.9.4](expressions.md#1294-logical-negation-operator)), while represented by the same lexical token (`!`), are distinct. Only the latter may be overriden ([§15.10](classes.md#1510-operators)), the definition of the null-forgiving operator is fixed. *end note* | |||
*Note*: The postfix null-forgiving and prefix logical negation operators ([§12.9.4](expressions.md#1294-logical-negation-operator)), while represented by the same lexical token (`!`), are distinct. Only the latter may be overridden ([§15.10](classes.md#1510-operators)), the definition of the null-forgiving operator is fixed. *end note* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be overloaded rather than overridden?
|
||
If the *primary_expression* of an *element_access* is: | ||
|
||
- a value of *array_type*, the *element_access* is an array access ([§12.8.12.2](expressions.md#128122-array-access)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something bothers me about the first part of this sentence; it doesn't quite sit right with me.
Would "a value of an array_type" be better? I'm unsure.
- The value of `P` is checked to be valid. If the value of `P` is `null`, a `System.NullReferenceException` is thrown and no further steps are executed. | ||
- If the preceding steps have produced a single index value of type `Range` then: | ||
- Let *L* be the length of the array referenced by `P`. | ||
- `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly a period or semi-colon instead of a comma? (These feel like two complete sentences, effectively.)
- Let *L* be the length of the array referenced by `P`. | ||
- `A` is checked to be valid with respect to *L* (§24.3), if it is not then a `System.ArgumentOutOfRangeException` is thrown and no further steps are executed. | ||
- The starting offset, *S*, and number of items, *N*, for `A` with respect to *L* are determined as described for `GetOffsetAndLength` (§24.3). | ||
- A new array is created from a shallow copy of the *N* elements of `P` starting at index *S*, if *N* is zero the new array has zero elements. This array becomes the result of the array access. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- A new array is created from a shallow copy of the *N* elements of `P` starting at index *S*, if *N* is zero the new array has zero elements. This array becomes the result of the array access. | |
- A new array is created from a shallow copy of the *N* elements of `P` starting at index *S*. If *N* is zero the new array has zero elements. This array becomes the result of the array access. |
@@ -2254,9 +2316,17 @@ The binding-time processing of an indexer access of the form `P[A]`, where `P` i | |||
- If `I` is applicable with respect to `A` ([§12.6.4.2](expressions.md#12642-applicable-function-member)) and `S` is a class type other than `object`, all indexers declared in an interface are removed from the set. | |||
- If the resulting set of candidate indexers is empty, then no applicable indexers exist, and a binding-time error occurs. | |||
- The best indexer of the set of candidate indexers is identified using the overload resolution rules of [§12.6.4](expressions.md#1264-overload-resolution). If a single best indexer cannot be identified, the indexer access is ambiguous, and a binding-time error occurs. | |||
- The index expressions of the *argument_list* are evaluated in order, from left to right. The result of processing the indexer access is an expression classified as an indexer access. The indexer access expression references the indexer determined in the step above, and has an associated instance expression of `P` and an associated argument list of `A`, and an associated type that is the type of the indexer. If `T` is a class type, the associated type is picked from the first declaration or override of the indexer found when starting with `T` and searching through its base classes. | |||
- The accessors of the best indexer are checked: | |||
- If the indexer access is the target of an assignment then the indexer shall have a set or ref get accessor, if not a binding-time error occurs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not thrilled about the comma here either, but within the context it's harder to fix.
### §hat-operator Hat operator | ||
|
||
The unary `^` operator is called the *hat* operator. The hat operator is not overloadable (§12.4.3) and there is a single predefined hat operator: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly, I like "from end operator" most as it corresponds with Index.FromEnd
. (I could live with "index-from-end operator" as well, to be even clearer...)
@@ -0,0 +1,309 @@ | |||
# 24 Extended Indexing and Slicing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm mildly amused that the name of the file doesn't occur anywhere within its title. How much do we care?
> | ||
> *end note* | ||
|
||
## 24.2 The Index type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I'm okay with defining the semantics of just Index and Range themselves, but not the semantics of how they're used.
Is the workload concern in terms of ongoing maintenance beyond the initial definition that has already been provided?
(No need to respond here - let's definitely discuss in the meeting.)
Alternative to #605