Skip to content

Commit c47220f

Browse files
authored
Start record positional field getters at 1. (#2771)
Fix #2638.
1 parent 5915f57 commit c47220f

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

accepted/future-releases/records/records-feature-specification.md

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Author: Bob Nystrom
44

55
Status: Accepted
66

7-
Version 1.18 (see [CHANGELOG](#CHANGELOG) at end)
7+
Version 1.20 (see [CHANGELOG](#CHANGELOG) at end)
88

99
## Motivation
1010

@@ -76,14 +76,14 @@ all.
7676

7777
Once a record has been created, its fields can be accessed using getters.
7878
Every named field exposes a getter with the same name, and positional fields
79-
expose getters named `$0`, `$1`, etc.:
79+
expose getters named `$1`, `$2`, etc.:
8080

8181
```dart
82-
var record = (1, a: 2, 3, b: 4);
83-
print(record.$0); // Prints "1".
84-
print(record.a); // Prints "2".
85-
print(record.$1); // Prints "3".
86-
print(record.b); // Prints "4".
82+
var record = ("ape", a: "bat", "cat", b: "dog");
83+
print(record.$1); // Prints "ape".
84+
print(record.a); // Prints "bat".
85+
print(record.$2); // Prints "cat".
86+
print(record.b); // Prints "dog".
8787
```
8888

8989
## Core library
@@ -129,15 +129,15 @@ not captured by the grammar. It is a compile-time error if a record has any of:
129129
* A field name that starts with an underscore.
130130

131131
* A field name that collides with the synthesized getter name of a positional
132-
field. *For example: `('pos', $0: 'named')` since the named field '$0'
132+
field. *For example: `('pos', $1: 'named')` since the named field "$1"
133133
collides with the getter for the first positional field.*
134134

135135
In order to avoid ambiguity with parenthesized expressions, a record with
136136
only a single positional field must have a trailing comma:
137137

138138
```dart
139-
var number = (1); // The number 1.
140-
var record = (1,); // A record containing the number 1.
139+
var number = (123); // The number 123.
140+
var record = (123,); // A record containing the number 123.
141141
```
142142

143143
The expression `()` refers to the constant empty record with no fields.
@@ -215,7 +215,7 @@ It is a compile-time error if a record type has any of:
215215
* A field name that starts with an underscore.
216216

217217
* A field name that collides with the synthesized getter name of a positional
218-
field. *For example: `(int, $0: int)` since the named field '$0' collides
218+
field. *For example: `(int, $1: int)` since the named field "$1" collides
219219
with the getter for the first positional field.*
220220

221221
### No record type literals
@@ -385,26 +385,26 @@ and `{int b, int a}` are identical to the type system and the runtime. (Tools
385385
may or may not display them to users in a canonical form similar to how they
386386
handle function typedefs.)
387387

388-
*Positional fields are not merely syntactic sugar for fields named `$0`, `$1`,
389-
etc. The records `(1, 2)` and `($0: 1, $1: 2)` expose the same *members*, but
390-
have different shapes according to the type system.*
388+
*Positional fields are not merely syntactic sugar for fields named `$1`, `$2`,
389+
etc. The records `('a', 'b')` and `($1: 'a', $2: 'b')` expose the same
390+
_members_, but have different shapes according to the type system.*
391391

392392
### Members
393393

394394
A record type declares all of the members defined on `Object`. It also exposes
395395
getters for each named field where the name of the getter is the field's name
396396
and the getter's type is the field's type. For each positional field, it exposes
397-
a getter whose name is `$` followed by the number of preceding positional fields
398-
and whose type is the type of the field.
397+
a getter whose whose type is the type of the field and whose name is `$n` where
398+
`n` is the field's `1`-based index in the positional fields.
399399

400400
For example, the record expression `(1.2, name: 's', true, count: 3)` has a
401401
record type whose signature is like:
402402

403403
```dart
404404
class extends Record {
405-
double get $0;
405+
double get $1;
406406
String get name;
407-
bool get $1;
407+
bool get $2;
408408
int get count;
409409
}
410410
```
@@ -516,7 +516,7 @@ The following example illustrates this:
516516
```dart
517517
// No static error.
518518
// Inferred type of the record is (int, double)
519-
(num, num) r = (3, 3.5)..$0.isEven;
519+
(num, num) r = (3, 3.5)..$1.isEven;
520520
```
521521

522522
Also note that implicit casts and other coercions are considered to be applied
@@ -644,7 +644,7 @@ var x = (a: say(1), b: say(2));
644644
var y = (b: say(3), a: say(4));
645645
```
646646

647-
*This program *must* print "1", "2", "3", "4", even though `x` and `y` are
647+
*This program _must_ print "1", "2", "3", "4", even though `x` and `y` are
648648
records with the same shape.*
649649

650650
### Field getters
@@ -694,11 +694,11 @@ as:
694694

695695
1. If `o` is not a record with the same shape as `r` then `false`.
696696

697-
1. For each pair of corresponding fields `rf` and `of` in unspecified order:
697+
2. For each pair of corresponding fields `rf` and `of` in unspecified order:
698698

699699
1. If `rf == of` is `false` then `false`.
700700

701-
1. Else, `true`.
701+
3. Else, `true`.
702702

703703
*The order that fields are iterated is potentially user-visible since
704704
user-defined `==` methods can have side effects. Most well-behaved `==`
@@ -828,6 +828,10 @@ library is sufficient to enforce this.*
828828

829829
## CHANGELOG
830830

831+
### 1.20
832+
833+
- Start positional record field getters at `$1`, not `$0` (#2638).
834+
831835
### 1.19
832836

833837
- Allow legacy libraries that don't support records to still be able to see the

0 commit comments

Comments
 (0)