Swift Regret: Protocol Syntax
Swift regret: protocol syntax. In ObjC subclassing and protocol adoption look different:
— Jordan Rose (@UINT_MIN) August 4, 2021
MyController: NSObject <UITableViewDelegate>
And so does using a protocol-typed value
NSObject *
id < UITableViewDelegate >
NSObject < UITableViewDelegate > *
[thread]
Part of the Swift Regrets series.
In Objective-C, subclassing and protocol adoption look different:
@interface MyController: NSObject <UITableViewDelegate>
And so does using a protocol-typed value:
NSObject *
id <UITableViewDelegate>
NSObject <UITableViewDelegate> *
In Swift we made those all uniform. Simpler is better, right?
class MyController: NSObject, UITableViewDelegate
NSObject
UITableViewDelegate
NSObject & UITableViewDelegate
But now you have weird rules about the order (class goes first so you don’t have to search for it). You have a syntax that’s uniform between structs and classes (and overloaded again for enums’ raw types) that means something slightly different in each case. And most importantly, when people write a function that works on a protocol, they use the protocol directly, instead of writing a generic function, because it’s so easy.
func update(_ controller: UITableViewController)
It’s not important in this example, but if you had to write, say, any UITableViewController
, maybe people would consider generics more. Doubly so if some UITableViewDelegate
were valid shorthand for a one-use generic. (Though with the way Swift generics work, a one-use generic is very similar to a one-use protocol value anyway, so at least locally the compiler could do some optimization.)
So in summary I think protocol value types shouldn’t have had the same syntax as concrete value types, and adopting protocols shouldn’t have had the same syntax as subclassing.