[swift-evolution] SR-104: Improve Crash-Safety when Importing Objective-C Code Without Nullability Attributes
Fabian.Ehrentraud at willhaben.at
Sat Dec 12 03:13:10 CST 2015
Am 12.12.2015 um 06:03 schrieb Douglas Gregor <dgregor at apple.com<mailto:dgregor at apple.com>>:
On Dec 11, 2015, at 12:08 AM, Fabian Ehrentraud <Fabian.Ehrentraud at willhaben.at<mailto:Fabian.Ehrentraud at willhaben.at>> wrote:
On 10.12.2015, at 23:28, Douglas Gregor <dgregor at apple.com<mailto:dgregor at apple.com>> wrote:
On Dec 10, 2015, at 1:22 PM, Fabian Ehrentraud <Fabian.Ehrentraud at willhaben.at<mailto:Fabian.Ehrentraud at willhaben.at>> wrote:
Most of the implicitly unwrapped optionals we currently get from (Objective-)C APIs can, in fact, never be nil. Forcing programmers to deal with all of these values as full optionals leads to a ton of optional-related boilerplate that doesn’t actual help users write better code. Rather, it dilutes the effectiveness of optionals as a language feature: optionals should mean “nil matters here, think about it carefully!”. But if some large number of optionals people deal with on a day-to-day basis are instead “the compiler didn’t know, so you have to write !”, the useful meaning of the “true” optionals gets lost in the noise.
I think exactly the opposite. If an API has not yet been audited, the client needs to consult the documentation if a return value can ever be nil. If not, she might explicitly and knowingly unwrap the value safely or non-safely. I deem this a good thing, as it prevents unknowingly unsafe use. I do not think that it would get in the way, as the syntactic sugar for Optionals is quite minimal. Also when the API gets audited for nullability later on, the compiler will hint which optional unwrappings have been rendered unnecessary.
You’re discounting my main argument, which is that the safety provided by optionals is contingent on the nil case being interesting most of the time. That’s generally true in “pure” Swift code—Swift programmers use optionals when nil matters—and it’s generally true in imported (Objective-)C code that has been audited, but your change would create a lot of optionals where “nil” isn’t actually interesting in practice.
Have I understood it right that your argument is that defaulting to Optionals would would make them loose their meaning and result in programmers just use ! too often, also in cases where the nil case should properly be handled? I see the point. And I'm thankful for this constructive discussion.
Nonetheless I think that Swift preventing unintentional mistakes would be something to strive for. Have you got alternative ideas on how to deal with the issue this proposal tries to address?
I honestly don’t have alternative ideas here—implicitly unwrapped optionals is the best solution that we could find to balance the goals of making it easy to write correct code vs. not pushing too much boilerplate on users, and while I want to continue to make them less common in Swift, I don’t think changing the Clang importer is the right answer.
Would it be technically possible to have a different behavior for Cocoa APIs vs. own Application Code and integrated 3rd-party Frameworks?
The Cocoa API is pretty well documented, and I think IUOs don't hurt too much there, as opposed to the other two. Also if nullabillity annotations are missing from the latter two, they can be added. So the necessary boilerplate !/? would remind the users in a safe manner.
I'm unhappy with defaulting to IUOs as it has a bad impact on mixed projects. In pure ObjC it was expected that nil could be returned but mostly ignored as it could not hurt if methods were called on it, so not too many crashes arose. In a pure Swift project one can stay away from IUOs and avoid that nil issue alltogether if one stays away from forced unwrapping. But as soon as the two are used together, for example when migrating to Swift, crashes can be hidden in every line. And there are no compiler warnings, no analyzer inspections or anything that can help to find these lines.
That said, here is an alternative idea. A new compiler warning "Access to Objective-C method/function/property/initializer that misses nullability annotations". I guess this warning should not be shown for Cocoa APIs.
Would this result in even more work than the original proposal? Would it harm productivity if "Treat warnings as errors" is activated?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the swift-evolution