- Proposal: SE-0122
- Author: James Froggatt
- Status: Scheduled for review July 20...25
- Review manager: Chris Lattner
Currently, subscript declarations follow the following model:
subscript(externalName internalName: ParamType) -> ElementType {
get { … }
set { … }
}
The initial keyword subscript
is followed by a parameter list, followed by an arrow to the accessed type. This proposal is to replace the arrow with a colon, to match accessor declarations elsewhere in the language.
Swift-evolution thread: Discussion thread topic for that proposal
The arrow, borrowed from function syntax, is very much out of place in this context, and so can act as a mental stumbling block. It is also misleading, as it implies that subscripts have the full capabilities of functions, such as the ability to throw. If throwing functionality were to be added to accessors, it is likely the specific get/set accessor would be annotated. In this case, the effects on a subscript's ‘function signature’ could become a source of confusion.
Subscripts act like parameterised property accessors. This means, like a property, they can appear on the left hand side of an assignment, and values accessed through subscripts can be mutated in-place. The colon has precedent in declaring this kind of construct, so it makes sense to reuse it here.
A simple replacement of ->
with :
in the declaration syntax.
This would change the above example to look like the following:
subscript(externalName internalName: ParamType) : ElementType {
get { … }
set { … }
}
Existing code would have to update subscripts to use a colon. This can be automated in a conversion to Swift 3 syntax.
The Swift core team has trialled this change internally, but backtracked due to readability concerns. This is something to bear in mind when considering this proposal.
The effect largely depends on coding style, which can match either of the following:
subscript(_ example: Type) : ElementType
subscript(_ example: Type): ElementType
This issue is most apparent in the latter example, which omits the leading space before the colon, as the colon blends into the closing bracket.
However, the real-world effect of this change is hard to predict, and subscript declarations are rare enough that the consequences of this change are very limited.
We could leave the syntax as it is, or use an alternative symbol, such as :->
or <->
.
We could also leave open the possibility of expanding function syntax with inout ->
.
Colons were chosen for this proposal because they have precedent elsewhere in the language, and are already reserved syntax.
This parameterised accessor syntax could be expanded in a future version of Swift, to support named accessors. This could look something like the following:
var image(for state: UIControlState) : UIImage? {
get {
…
}
set {
…
}
}
button.image(for: .normal) = image