You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/NNNN-init-accessors.md
+42-28Lines changed: 42 additions & 28 deletions
Original file line number
Diff line number
Diff line change
@@ -57,7 +57,7 @@ This proposal adds _`init` accessors_ to opt computed properties on types into v
57
57
structAngle {
58
58
var degrees: Double
59
59
var radians: Double {
60
-
init(newValue,initializes: degrees) {
60
+
init(newValue) initializes(degrees) {
61
61
degrees = newValue *180/ .pi
62
62
}
63
63
@@ -75,16 +75,16 @@ struct Angle {
75
75
}
76
76
```
77
77
78
-
The signature of an `init` accessor specifies up to two sets of stored properties: the access dependencies (via `accesses`) and the initialized properties (via `initializes`). Access dependencies specify the other stored properties that can be accessed from within the `init` accessor (no other uses of `self` are allowed), and therefore must be initialized before the computed property's `init` accessor is invoked. The `init` accessor must initialize each of the initialized stored properties on all control flow paths. The `radians` property in the example above specifies no access dependencies, but initializes the `degrees` property, so it specifies only `initializes: degrees`.
78
+
The signature of an `init` accessor specifies up to two sets of stored properties: the properties that are accessed (via `accesses`) and the properties that are initialized (via `initializes`) by the accessor. `initializes` and `accesses` are side-effects of the `init` accessor. Access effects specify the other stored properties that can be accessed from within the `init` accessor (no other uses of `self` are allowed), and therefore must be initialized before the computed property's `init` accessor is invoked. The `init` accessor must initialize each of the initialized stored properties on all control flow paths. The `radians` property in the example above specifies no access effect, but initializes the `degrees` property, so it specifies only `initializes: degrees`.
79
79
80
-
Access dependencies allow a computed property to be initialized by placing its contents into another stored property:
80
+
Access effects allow a computed property to be initialized by placing its contents into another stored property:
81
81
82
82
```swift
83
83
structProposalViaDictionary {
84
84
privatevar dictionary: [String: String] = [:]
85
85
86
86
var title: String {
87
-
init(newValue,accesses: dictionary) {
87
+
init(newValue) accesses(dictionary) {
88
88
dictionary["title"] = newValue
89
89
}
90
90
@@ -93,7 +93,7 @@ struct ProposalViaDictionary {
93
93
}
94
94
95
95
var text: String {
96
-
init(newValue,accesses: dictionary) {
96
+
init(newValue) accesses(dictionary) {
97
97
dictionary["text"] = newValue
98
98
}
99
99
@@ -123,7 +123,7 @@ struct Wrapper<T> {
123
123
structS {
124
124
privatevar _value: Wrapper<Int>
125
125
var value: Int {
126
-
init(newValue,initializes: _value) {
126
+
init(newValue) initializes(_value) {
127
127
self._value=Wrapper(wrappedValue: newValue)
128
128
}
129
129
@@ -149,33 +149,25 @@ This proposal allows macros to model the following property-wrapper-like pattern
149
149
This proposal adds new syntax for `init` accessor blocks, which can be written in the accessor list of a computed property. Init accessors add the following production rules to the grammar:
The `identifier` in an `init-dependency-clause`, if provided, is the name of the parameter that contains the initial value. If not provided, a parameter with the name `newValue` is automatically created.
166
+
The `identifier` in an `init-accessor-parameter`, if provided, is the name of the parameter that contains the initial value. If not provided, a parameter with the name `newValue` is automatically created.
175
167
176
168
### `init` accessor signatures
177
169
178
-
`init` accessor declarations can optionally specify a signature. An `init` accessor signature is composed of a parameter for the initial value, a list of stored properties that are initialized by this accessor specified with the `initializes:` label, and a list of stored properties that are accessed by this accessor specified with the `accesses:` labe, all of which are optional:
170
+
`init` accessor declarations can optionally specify a signature. An `init` accessor signature is composed of a parameter for the initial value, a list of stored properties that are initialized by this accessor specified with the contextual `initializes` keyword, and a list of stored properties that are accessed by this accessor specified with the contextual `accesses` keyword, all of which are optional:
179
171
180
172
```swift
181
173
structS {
@@ -184,7 +176,7 @@ struct S {
184
176
var _x: Int
185
177
186
178
var x: Int {
187
-
init(newValue,initializes: _x,accesses: readMe) {
179
+
init(newValue) initializes(_x) accesses(readMe) {
188
180
print(readMe)
189
181
_x = newValue
190
182
}
@@ -216,7 +208,7 @@ struct S {
216
208
var x1: Int
217
209
var x2: Int
218
210
var computed: Int {
219
-
init(newValue,initializes: x1, x2) { ... }
211
+
init(newValue) initializes(x1, x2) { ... }
220
212
}
221
213
222
214
init() {
@@ -233,7 +225,7 @@ struct S {
233
225
var x2: Int
234
226
var x3: Int
235
227
var computed: Int {
236
-
init(newValue,initializes: x1, x2) { ... }
228
+
init(newValue) initializes(x1, x2) { ... }
237
229
}
238
230
239
231
init() {
@@ -251,7 +243,7 @@ struct S {
251
243
var x: Int
252
244
var y: Int
253
245
var point: (Int, Int) {
254
-
init(newValue,initializes: x, y) {
246
+
init(newValue) initializes(x, y) {
255
247
(self.x, self.y) = newValue
256
248
}
257
249
get { (x, y) }
@@ -273,7 +265,7 @@ If a struct does not declare its own initializers, it receives an implicit membe
273
265
structS {
274
266
var _x: Int
275
267
var x: Int {
276
-
init(newValue,initializes: _x) {
268
+
init(newValue) initializes(_x) {
277
269
_x = newValue
278
270
}
279
271
@@ -296,13 +288,13 @@ init(x: Int, y: Int) {
296
288
}
297
289
```
298
290
299
-
A memberwise initializer cannot be synthesized if a stored property that is an `accesses:` dependency of a computed property is ordered after that computed property in the source code:
291
+
A memberwise initializer cannot be synthesized if a stored property that is an `accesses` effect of a computed property is ordered after that computed property in the source code:
300
292
301
293
```swift
302
294
structS {
303
295
var _x: Int
304
296
var x: Int {
305
-
init(newValue,initializes: _x, reads: y) {
297
+
init(newValue) initializes(_x) accesses(y) {
306
298
_x = newValue
307
299
}
308
300
@@ -335,7 +327,29 @@ Note that macro-expanded declarations are ordered after the attached-to declarat
335
327
336
328
## Implications on adoption
337
329
338
-
Because `init` accessors are always called from within the defining module, adopting `init` accessors is an ABI-compatible change. Adding an `init` accessor to an existing property also cannot have any source compatibility impact outside of the defining module; the only possible source incompatibilities are on the generated memberwise initializer (if new entries are added), or on the type's `init` implementation (if new initialization dependencies are added).
330
+
Because `init` accessors are always called from within the defining module, adopting `init` accessors is an ABI-compatible change. Adding an `init` accessor to an existing property also cannot have any source compatibility impact outside of the defining module; the only possible source incompatibilities are on the generated memberwise initializer (if new entries are added), or on the type's `init` implementation (if new initialization effects are added).
331
+
332
+
## Alternatives considered
333
+
334
+
A previous version of this proposal specified init accessor effects in the parameter list using special labels:
335
+
336
+
```swift
337
+
structS {
338
+
var _x: Int
339
+
var x: Int {
340
+
init(newValue, initializes: _x, accesses: y) {
341
+
_x = newValue
342
+
}
343
+
344
+
get { _x }
345
+
set { _x = newValue }
346
+
}
347
+
348
+
var y: Int
349
+
}
350
+
```
351
+
352
+
This syntax choice is misleading because the effects look like function parameters, while `initializes` behaves more like the output of an init accessor, and `accesses` are not explicitly provided at the call-site. Conceptually, `initializes` and `accesses` are side effects of an `init` accessor, so the proposal was revised to place these modifiers in the effects clause.
0 commit comments