[swift-evolution] Swift null safety questions

Austin Zheng austinzheng at gmail.com
Mon Mar 6 21:57:02 CST 2017


I've worked on several large Swift codebases for large, prominent companies and use of '!' was extremely rare and highly discouraged. It showed up most frequently as the type for @IBOutlet properties, which would not be relevant when programming a server application.

I completely agree with you that the Xcode fix-it is terrible and should be removed or replaced, but unfortunately it's been made clear that changes to Xcode are outside the purview of swift-evolution. You should definitely file a Radar, though.

Best,
Austin

> On Mar 6, 2017, at 7:52 PM, Elijah Thomas Johnson <tomac120 at gmail.com> wrote:
> 
> Well, I think that it is far more ingrained into the language and its daily use than you might realize.
> 
> At the very least, someone should correct the XCode warning that says (to paraphrase) “code does not comple, double click to insert optional here” and create some code-analysis warnings against the practice of forced unwrap where it can be replaced.
> 
> I’ve been a full year with Swift now, and just a week or two ago I learned about this optional binding feature. You could say I’m not devoted enough, but I’ve not had any crashing issues, XCode just told me to insert force-unwrap and thats what I did.
> 
> If this whole “force-unwrap” thing isn’t the intended way of doing things, that could be made a bit more explicit I think.
> 
> Here’s a screenshot of what I am referring to: https://snag.gy/dH6twR.jpg <https://snag.gy/dH6twR.jpg>
> 
> Says: Fix it: Insert !
> Should say: Fix it: Use optional binding.
> 
> Xcode might not be in the Swift evolution domain, but I think the idea of warnings for "unnecessary use of !” are.
> 
> On March 6, 2017 at 9:47:04 PM, Austin Zheng (austinzheng at gmail.com <mailto:austinzheng at gmail.com>) wrote:
>> Swift already is an unmanaged language, and is far closer to C++ than Java. There is no equivalent to the CLR or JVM and it is trivially easy to call into C code or the unsafe APIs and do nearly anything that C can do with regard to direct access to memory.
>> 
>> The force-unwrap operator was never intended to model a Java-style runtime exception. Instead, it is an assertion which indicates a programmer logic error. The preferred way to handle an optional at runtime has always been to use the conditional-unwrapping functionality the language offers. The correct way to report errors at runtime that aren't due to programmer error is through the do-try-catch mechanism. Pervasive, unnecessary use of '!' is a project management and/or developer competence issue, and not something the language should go out of its way to fix.
>> 
>> Sugaring 'if let' for programmer convenience is something on the commonly rejected proposals list: https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md <https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md>
>> 
>> Regards,
>> Austin
>> 
>> 
>> On Mon, Mar 6, 2017 at 6:27 PM, Elijah Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> Additionally, not discarding previous comments, one way the language could be improved is by replacing (or rather augmenting) optional binding with a faster syntax.
>> 
>> ex.
>> 
>> func test( name : String?, name2 :String? ){
>>      name! , name2! {
>> // inside this block, “name” and “name2” are non-optional
>>     } else {
>>       // no forced unwrapping, just optional else case
>>    }
>> }
>> 
>> Whereas the alternative (current optional binding), requires a re-definition of variables and an additional “if” operator. Besides the extra characters involved in typing and reading it, usually variables have specific names that the user does not want to augument.
>> 
>> func test( name : String?, name2 :String? ){
>>     if let nameUnwrapped = name , let name2Unwrapped = name2 {
>> 
>>     } else {
>>    }
>> }
>> 
>> func test( name : String?, name2 :String? ){
>>     guard let nameUnwrapped = name , let name2Unwrapped = name2 else {
>> 
>>     }
>> 
>> }
>> 
>> The fact that we don’t need a “nameUnwrapped” variable (which is unsightly and requires refractoring) is one thing that still makes forced unwrapping still very much a necessary or common part of Swift coding, even where it could be replaced with optional binding.
>> 
>> 
>> 
>> 
>> On March 6, 2017 at 7:20:40 PM, Elijah Johnson (ejrx7753 at gmail.com <mailto:ejrx7753 at gmail.com>) wrote:
>> 
>>> Hi,
>>> 
>>> I’ve been recently considering Swift on the server-side, and there came up the question, “what happens when a null optional is forcibly unwrapped?” and the answer was clearly that not only would the request crash, but the entire server would also crash, since the server itself is/would be also written in Swift.
>>> 
>>> I think that this highlights serveral weaknesses in Swift’s “null safety” attempts. The first is that there needs to be a way to isolate blocks of code so that a “null pointer exception” does not crash the system. I think it is fair to say, in the language of Java, that these are really “runtime exceptions” and for some reason are being treated as segmentation faults would be in C/C++. In my opinion, the existence of these things has the ability to bring Swift down below Java and closer to an unamanged language. Not really sure why it would ever be desireable, but in terms of server-side programming, it is definitely a serious issue.
>>> 
>>> Secondly, Swift’s “null safety” is really completely undermined by these “force-unwrap” errors. I agree with the usage of new language features like guard, optional binding, etc to remove a null value, but I see this force-unwrap as extremely pervasive for a lot of reasons:
>>> 
>>> 1. When porting code from a C style language to Swift, force-unwrap is needed to make the code work without refractoring.
>>> 2. XCode itself reccomends this operator and when it is used to satisfy a requirement, then it can be left in the code
>>> 3. Some styles of coding just can’t work without force-unwrap.
>>> 
>>> I don’t think the logic of making the consequences extreme for making a mistake are a rational for making better coders. In fact, I personally see the “force-unwrap” operator having very great potential usage as a deliberate assertion exception - the programmer demands that a certain value be non-null for execution to continue, only there should be a proper scope and context where these exceptions can propogate to. On debug modes, one might want it to pause on the line, but for other uses, it should be caught IMO - on regular code by the user, and inside dispatch blocks by the queue itself. For a multithreaded app or server to exit, the user should have to explicitly write exit(0), isn’t this the goal of a managed language? Maybe in some cases, Apple will want the program to crash, but if Swift is given an audience not just with Apple hardware, then it should have more flexibility IMO.
>>> 
>>> Elijah
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170306/2a1614b9/attachment.html>


More information about the swift-evolution mailing list