App Developers on Swift Evolution
A recent thread on the swift-evolution mailing list has me very concerned. My professional interests are primarily around developing productivity apps for end users. More people from our slice of the Apple developer community need to get involved. Perhaps this thread can be a call to action.
I’m incredibly impressed with the work Apple has done to make Swift truly an open source project with the community driving discussion. As someone who’s spent some time doing language design work (MultiJava, JML, MAO), I’m particularly enjoying the proposals and discussions regarding possible improvements to the language and libraries. These mostly happen on swift-evolution (archive here, sign up here, description of the evolution process here).
As you’d expect from a just-opened community like this, swift-evolution is high volume. A great many of the suggestions aren’t very well considered. (I’d list examples, but don’t want to call out people who are earnestly trying to contribute.) Other suggestions primarily come down to “just syntax”. For example, this proposal to “Require self for accessing instance members” and this (accepted) proposal to “Remove C-style for-loops with conditions and incrementers” don’t inheritly change the language or what we can do with it.
On the other hand, there are some suggestions that will have long term effects on the language and the ecosystem that develops around it. These are the ones that I find most interesting, because they’ll have outsized effects on the language I’m likely to use for the rest of my career. An example of this is a discussion thread on “Final by default for classes and methods”.
I often just dip a toe into the water of these interesting threads to check the temperature of the conversation and to see if members of the Swift core team are chiming in. Partly I’m interested in how the team is fostering community — they’ve been incredibly gracious — and partly I suspect suggestions that provoke core team interest are more likely to become formal proposal and be considered for inclusion in the language.
A Surprising Direction
In this spirit, I was skimming the suggestion to make classes and methods
final by default. The thread starts here and ends here at the moment. Browsing long threads in the web interface is … challenging, so I’ll recap.
Here’s the core of the suggestion:
“It is not uncommon to have a need for a reference type without a need for inheritance. Superclasses should be intentionally designed to be subclasses and the author required to opt-in to subclassing and member overrides where that is required by the design.”
That is, the suggestion is that subclassing classes and overriding methods should be implicitly banned unless the framework author takes specific action to permit such indignities. The idea has evolved a bit over the last two+ weeks, to suggest that this implicit ban only apply across module boundaries.
I was shocked to find many members of the Swift team at Apple agreeing with this suggestion. When I’d mentioned the suggestion to co-workers and to friends in the app development community, to a person they said it was ridiculous. Most made some variation of the argument that I posted to the mailing list:
Anyone who tries to ship products on release day of Apple’s operating system updates spends most of August and September writing horrible hacks so that their users are insulated from OS bugs as much as possible. All software has bugs, frameworks included. Please don’t take away our tools for working around those bugs. Making classes final by default assumes a level of perfection on the part of framework developers that is not achievable.
Yes, subclassing a class that wasn’t designed to be subclassed has serious risks. Thoughtful developers sometimes take on those risks in order to serve their customers.
Frankly, I think having
finalin the language at all is a mistake. While I agree that we should prefer composition to inheritance*, declaring things final is hubris. The only reasonable use case I’ve seen is for optimization, but that smacks of developers serving the compiler rather than the converse. Bringing an analog of
NS_REQUIRES_SUPERto Swift would be most welcome; that’s as far as I’d go down the path of dictating framework usage.
*- and am thrilled with the property behaviors proposal for this use case
I was further shocked when Jordan Rose at Apple replied (elisions mine):
Okay, so I probably shouldn’t be putting this so bluntly, but the ship has already sailed on this. Supporting arbitrary code injection into someone else’s framework is a non-goal for Swift, perhaps even an anti-goal.
[…substantial detail elided…]
If you replace a method on someone else’s class, you don’t actually know what semantics they’re relying on. Of course Apple code will have bugs in it. Trying to patch over these bugs in your own code is (1) obviously not an answer Apple would support, but also (2) fraught with peril, and (3) likely to break in the next OS release.
TLDR: It’s already unsafe to do this with the existing set of Swift features. Yes, this makes things “worse”, but it’s not something we’re interested in supporting anyway.
That prompted me to write:
Presumably a goal for Swift is that application developers will use it to build user-facing apps for Apple’s platforms. And presumably a goal for Apple is that developers help promote Apple’s platforms by shipping apps that take advantage of the new OS features when they ship. I fear that you and others dramatically underestimate the difficultly of doing that. I acknowledge your three points. But understand that we are professionals trying to serve our mutual customers. Temporary hacks in the service of shipping is the nature of the business.
I don’t know how to make the case more strongly than I already have. This thread makes me worry that the team does not understand what it’s like for third party developers trying to serve our mutual customers.
Then I got snotty on Twitter:
Very troubling thread on making final default for classes/methods. Swift team seems hostile to app developers.
Here’s the Deal
Doug Gregor rightly called me out for painting with too broad a brush. That said, I still fear that the team fails to understand how hard it is to ship on Apple’s platforms. As third party developers we:
- don’t have the code for Apple’s frameworks,
- can’t communicate with the framework authors, and
- can’t even attempt to change the priority of a framework bug when it’s critical to our “tent pole” features.
Swift does help us avoid major classes of bugs. Swift does not mean that Apple will ship bug-free frameworks. All software has bugs. As app developers we need tools to work around Apple’s bugs in the service of our customers.
So, What’s to be Done?
I love that Apple engineers are actively posting on the mailing lists. I don’t want my little snit to suppress that, and certainly don’t think I really have any influence on that one way or another.
The beauty of a community process is that all of us can participate. If you’re an app developer on Apple’s platforms, please sign up for the swift-evolution mailing list. You don’t even have to read it. Just set up a rule to file the messages.
Once a week, or when people lose their shit on twitter, take a look to see which threads are hot. If you see a proposal gaining traction that you know would make it harder to ship apps, well, you know where the reply button is. And if your reaction to
final-as-default matched mine, that thread might be a good place to start.
We need to step up and be a part of the community. Otherwise we may find that we’re developing with a language that doesn’t work for our needs.