As Swift’s 10th anniversary approaches it’s tempting to look back at what Swift has become and the journey it has taken. To be honest I wouldn’t have changed much but here's my personal list of things that might have been.
First, a couple of design decisions that could have gone differently:
Generic-like protocol associated type syntax?
I sometimes wonder if the syntax for associated types for protocols could have been more generic-like. The semantics and implementation would have been the same, just the syntax for introducing the associated type name could have been something more familiar along the lines of:
protocol Incrementable<Value = Double> {
var value: Value { get }
func incremented() -> Value
}
instead of:
protocol Incrementable {
associatedtype Value = Double
var value: Value { get }
func incremented() -> Value
}
It would still be possible to introduce this as an alternative syntax and this might make the concept more approachable to people coming from other languages.
It’s a fairly arbitrary opinion but I wish there wasn’t a Substring
type. Swift's no compromise String abstraction was already a bit of a handful without adding this extra complexity. StringProtocol
might have been useful if NSString
conformed to it but I guess that’s all water under the bridge. There was a thread about it
I share the view that SE0007 and SE0111 were unfortunate.
That’s a pretty short list of gripes all things considered but I have a longer list of features that could have been but never were. Many might have been "nice to have".
1) Custom implicit conversions
At times Swift’s type system is a tad strict and while many of the most important automatic conversions have been hard coded into the compiler it might have been nice to have a mechanism whereby you and I could add our own implicit conversions to tune the compiler down a bit e.g. Int32 to Int, UnsafePointer to String etc. I looked at this for a while and believe it could have been done without slowing down type checking
2) Lightweight sub-typing
It occurred to me you could have a subtypealias
declaration to create what are known as “new types”. There was a pitch about this but unfortunately it was subject to a certain amount of gleeful pedantry early on and didn’t progress any further. I still think it would be a useful addition to the language though I’m under no illusions how big a change it would be to what constitutes a type in the compiler.
3) Lintable force unwrap.
Though it is true the Swift compiler's purpose is to compile source not judge it, I feel it could afford to be more opinionated and allow a few opt-in linting options e.g. for forced unwrap usage.
4) Suppressible warnings.
A related topic is that of being able suppress warnings. I agree that a compiler option is probably the wrong idea as Swift source should’t require build options to compile for fear of “dialects". A better idea might have been a #supressWarning(“The warning message”)
source directive you could leave on the previous line. In this way marginal code could compile cleanly but still be highlighted in the source.
5) Retroactively conforming protocol extensions.
i.e. being able write an extension on a protocol that introduces a conformance to a protocol. A deceptively simple thing to want that leads to all sorts of difficulties when you come to implement it. I looked at it for a while
6) Multi-type extensions
Using protocol extensions to give behaviours to a category of types isn’t always performant. Would it be possible to write an extension on a list of types to avoid replication of code?
extension Int8, Int16, Int32 {
The use of comma conflicts with specifying multiple clauses after a where
on the extension but one could almost imagine it could be supported?
7) Single quoted character literals
I’ve banged on about this enough already.
8) Values for -D compiler option like C.
There was a pitch
9) Conditionals in collections
I’d have liked to seen this but we failed at the last hurdle.
Anyway, that’s my 2¢. What would be your priorities?