[swift-evolution] [Proposal] Remove force unwrapping in function signature.

Saagar Jha saagarjha28 at gmail.com
Wed Jun 29 00:04:26 CDT 2016


Yep, that’s what I meant. I should probably go back and re-write the
proposal if it’s not clear.

BTW, when does the window for proposals close? Is this in the scope for
Swift 3?


On Tue, Jun 28, 2016 at 9:54 PM David Waite <david at alkaline-solutions.com>
wrote:

> Hi Saagar,
>
> If I understand your proposal correctly, you are suggesting that we remove
> T! and just force people to use T? or T.  This is a commonly rejected
> proposal (though not on the list yet) that frequently comes up.  The
> problem with your proposal is that you don’t provide any solutions to the
> problems that T! is currently solving: that of two-phase initialization and
> importing of APIs that have not been nullability audited.  It isn’t
> pragmatic to handle these cases as T?
>
> -Chris
>
>
> Chris,
>
> I believe he only is speaking to removing the ability to use IUOs as
> function parameters, not as properties (for 2-phase init) or return values
> (for unaudited API). The question would be what the impact would be of
> unaudited API being imported as accepting an explicit optional rather than
> IUO.
>
> -DW
>
>
> Remove implicitly unwrapped optionals as function parameters
>
>    - Proposal: SE-NNNN
>    - Author: Swift Developer <https://github.com/swiftdev>
>    - Status: *Awaiting review*
>    - Review manager: TBD
>
> Introduction
>
> Swift, in contrast with Objective-C, makes a distinction between values
> that may be nil and values that can never be nil through its use of
> Optionals. Due to the fact that Objective-C does not make this distinction,
> Objective-C functions that do not use the Nullability
> <https://developer.apple.com/swift/blog/?id=25> annotations are imported
> with parameters of the implicitly unwrapped optional type. Unfortunately,
> this allows users to write their own Swift code that looks like this:
>
> func foo(bar: Int!) {
>     //…
> }
>
> Due to the confusion this may cause, we would like to propose the *removal
> of implicitly unwrapped optionals as function parameters*. Discussion on
> this topic may be found here
> <http://article.gmane.org/gmane.comp.lang.swift.evolution/21730/>.
> Motivation
>
> Implicitly unwrapped optionals are currently allowed in function
> declarations. Consider the following function:
>
> func triple(forceUnwrapping aNumber: Int) -> Int {
>     return aNumber * 3
> }
>
> let possiblyNil = Int("foo")
> triple(forceUnwrapping: possiblyNil)
>
> possiblyNil is an Int?; thus, this example will not compile due to
> triple(forceUnwrapping:) expecting an Int. It is easy to imagine a Swift
> beginner writing code that looks like this to "fix" the problem:
>
> func triple(forceUnwrapping aNumber: Int!) -> Int {
>     return aNumber * 3
> }
>
> let possiblyNil = Int("foo")
> triple(forceUnwrapping: possiblyNil)
>
> While this version compiles, it crashes due to the force unwrapping of a
> nil value. Unfortunately, the compiler "hides" this fact by making it
> seem like it's acceptable to pass in nil–it doesn't make the forced
> unwrapping *explicit*.
> Proposed solution
>
> The safest solution, in this case, is to prevent the use of implicitly
> unrwapped optionals in function signatures. By forcing users to write
>
> func triple(forceUnwrapping aNumber: Int) -> Int {
>     return aNumber * 3
> }
>
> or
>
> func triple(forceUnwrapping aNumber: Int?) -> Int {
>     return aNumber * 3
> }
>
> the compiler will complain, reminding users that they should probably
> attempt to safely unwrap the optional before using it.
> Detailed design
>
> The proposal will prevent the use of implicitly unwrapped optionals in
> function signatures for both Swift code as well as imported Objective-C
> code. As non-annotated Objective-C functions are currently imported as
> implicitly unwrapped, they will be converted to optionals as a preliminary
> step. Non-audited frameworks can be audited in the future so that they can
> be tagged with _Nonnull if necessary.
> Impact on existing code
>
> This is a proposal is a source breaking change, but it should be easily
> mitigated using a migrator. Existing functions with implicitly unwrapped
> optionals can be changed to optional; users can easily shadow variables
> with a guard or change their function to non-optional.
> Alternatives consideredImporting Objective-C functions as-is, but
> disallowing implictly unwrapped optionals in Swift code
>
> This reduces the burden on existing frameworks and adding Nullability
> annotations, but creates a sort of disconnect between Objective-C and Swift
> in that it prevents Swift developers from writing functions with implicitly
> unwrapped optionals.
> Doing nothing
>
> Obviously, this has the benefit of keeping the current behavior and not
> requiring a migrator. However, I believe that the unsafe behavior that this
> encourages is not worth keeping.
>
>
> On Mon, Jun 27, 2016 at 1:35 PM Dennis Lysenko <dennis.s.lysenko at gmail.com>
> wrote:
>
>> +1. This is sort of how Kotlin does it. In Kotlin, IUOs are strictly a
>> carryover from Java. They show up in method signatures from
>> non-nullable-annotated Java, but you can't define a new method that takes
>> e.g. an Int!.
>>
>> The limited scope of this proposal is ideal in my opinion since we see
>> areas where IUOs are clearly useful (ViewControllers for instance) but
>> defining new functions that take implicitly unwrapped optionals makes no
>> sense. If you need to pass a IUO at the call site, you can define the
>> function taking a non-optional value and pass the IUO to that. There is no
>> use case I can think of for having it in method/function signatures.
>>
>> RE: language inconsistencies, there is no such issue in practice in
>> Kotlin where there is also inconsistency in the same vein. I see it simply
>> as a compromise that achieves the goal of keeping a useful feature but
>> discouraging its overuse by forbidding its use in places where its use
>> could confuse and snowball down the line into teaching developers worse
>> code quality.
>>
>> On Mon, Jun 27, 2016 at 12:04 PM Charlie Monroe via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> Ok, I see - though I find myself using occasionally IUOs in Swift as
>>> well - e.g. when you can't use the default values because they depend on
>>> self, etc.
>>>
>>> Eliminating it just from method signatures IMHO brings an incosistency
>>> into the language. Why would you eliminate it only from method signatures -
>>> this proposal mentioned importing ObjC API in the beginning - why not then
>>> mark those properties all as optional as well? IUOs are scheduled to be
>>> removed completely once the language reaches a point where it can handle
>>> most scenarios otherwise...
>>>
>>> Try to imagine some APIs brought to Swift with default being nullable:
>>>
>>> /// Imported from
>>> public class NSOrderedSet : NSObject, NSCopying, NSMutableCopying,
>>> NSSecureCoding, NSFastEnumeration {
>>>
>>>     public var count: Int { get }
>>>     public func objectAtIndex(idx: Int) -> AnyObject?
>>>     public func indexOfObject(object: AnyObject?) -> Int
>>>     public init()
>>>     public init(objects: UnsafePointer<AnyObject?>, count cnt: Int)
>>>     public init?(coder aDecoder: NSCoder?)
>>> }
>>>
>>> This doesn't make much sense - mostly objectAtIndex(_:).
>>>
>>> On Jun 27, 2016, at 8:35 PM, Saagar Jha <saagarjha28 at gmail.com> wrote:
>>>
>>> I think you’re mistaking the scope of the proposal. It’s simply removing
>>> IUOs in *function signatures*, not throughout the language.
>>>
>>> On Mon, Jun 27, 2016 at 11:31 AM Charlie Monroe via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>>> There are many useful cases for IUO in Swift - mostly when you have
>>>> variables that cannot be calculated at the point of calling super.init(),
>>>> but are guaranteed to be filled during initialization - i.e. during the
>>>> lifetime of the object, the value is nonnil, but may be nil for a short
>>>> period of time.
>>>>
>>>> Or @IBOutlets. Making all @IBOutlets optionals would make the code
>>>> either riddled with ! or shadowed locally re-declared instance members.
>>>>
>>>>
>>>> > On Jun 27, 2016, at 8:12 PM, Jean-Daniel Dupas <mailing at xenonium.com>
>>>> wrote:
>>>> >
>>>> > Maybe we can prohibit it in Swift function declaration, and allow it
>>>> only when importing native code.
>>>> >
>>>> > As David, I don’t see any compelling reason to allow such construct
>>>> in Swift.
>>>> >
>>>> >> Le 27 juin 2016 à 10:39, Charlie Monroe via swift-evolution <
>>>> swift-evolution at swift.org> a écrit :
>>>> >>
>>>> >> When you import ObjC code that has no nullability annotation, IUO
>>>> make sense since:
>>>> >>
>>>> >> - they can be checked against nil
>>>> >> - typically, most values in APIs are nonnull (looking at Foundation,
>>>> for example, which is why Apple has the NS_ASSUME_NONNULL_BEGIN to mark
>>>> entire regions as nonnull, yet there is no NS_ASSUME_NULL_BEGIN)
>>>> >>
>>>> >> Importing them as optionals would make it really hard to work with
>>>> the code - whenever you get a value, it's an optional, even in cases where
>>>> it makes no sense and adding ! to unwrap the optional is not a great
>>>> solution. And the other solution is to use guards everywhere.
>>>> >>
>>>> >> IMHO the IUO is a nice (temporary) solution for using un-annotated
>>>> code until it is. But the "pressure" should be applied on the ObjC code.
>>>> >>
>>>> >>> On Jun 27, 2016, at 10:03 AM, David Rönnqvist <
>>>> david.ronnqvist at gmail.com> wrote:
>>>> >>>
>>>> >>> I don’t know about the chances of getting approved, but I think
>>>> this is something worth discussing.
>>>> >>>
>>>> >>> It might just be my ignorance, but I can’t think of a good reason
>>>> why a function argument would be force unwrapped. Either it’s non-null and
>>>> the caller is expected to unwrap it or it’s nullable and the method is
>>>> expected to handle the nil value. So I’m positive to that part of the
>>>> proposal.
>>>> >>>
>>>> >>> As to what we should do with the generated interfaces of
>>>> Objective-C code that hasn’t been annotated with nullability, I think that
>>>> needs input from more people to find the preferred solution.
>>>> >>>
>>>> >>> Once that’s been discussed some more, I’d be willing to write up a
>>>> formal proposal if you don’t feel like it (assuming the discussion leads
>>>> somewhere).
>>>> >>>
>>>> >>> - David
>>>> >>>
>>>> >>>
>>>> >>>> On 27 Jun 2016, at 06:28, Charlie Monroe via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>> >>>>
>>>> >>>> See
>>>> https://github.com/apple/swift-evolution/blob/master/process.md - you
>>>> would need to make an official proposal and submit it as pull request. But
>>>> given the reaction here, it's unlikely to get approved.
>>>> >>>>
>>>> >>>> Also, the ObjC code without nullability is getting fairly rare -
>>>> all Apple's frameworks are with nullability information (as far as I've
>>>> checked) in macOS 10.12, iOS 10. Third party libraries should be updated to
>>>> use nullability (and most libraries that are maintained already do).
>>>> >>>>
>>>> >>>>
>>>> >>>>> On Jun 25, 2016, at 5:13 PM, Spromicky via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>> >>>>>
>>>> >>>>> So, its proposal is dead, or what we must to do to force it to
>>>> swift-evolution repo on GitHub?
>>>> >>>>>
>>>> >>>>>> Hello, everyone!
>>>> >>>>>>
>>>> >>>>>> I wanna propose to you to remove force unwrapping in fuction
>>>> signature for swift code. That no sense in clear swift code. If we wanna
>>>> use some optional value as function param, that is not optional, we must
>>>> unwrap it before function call.
>>>> >>>>>> People who new in swift look at how they old Obj-C code (without
>>>> nullability modifiers) translate in to swift:
>>>> >>>>>>
>>>> >>>>>> Obj-C:
>>>> >>>>>> - (void)foo:(NSInteger)bar {
>>>> >>>>>> //...
>>>> >>>>>> }
>>>> >>>>>>
>>>> >>>>>> Swift transaliton:
>>>> >>>>>> func foo(bar: Int!) {
>>>> >>>>>> //...
>>>> >>>>>> }
>>>> >>>>>>
>>>> >>>>>> And think that force unwrapping in signature is good practice.
>>>> And start write functions in clear swift code like this:
>>>> >>>>>>
>>>> >>>>>> func newFoo(bar: Int!) {
>>>> >>>>>> //...
>>>> >>>>>> }
>>>> >>>>>>
>>>> >>>>>> and use it like this:
>>>> >>>>>>
>>>> >>>>>> let bar: Int? = 1
>>>> >>>>>> newFoo(bar)
>>>> >>>>>>
>>>> >>>>>> And it really work, and they does not think that this can crash
>>>> in case if `bar` will be `nil`.
>>>> >>>>>> But in clear swift we wanna work with parametrs in function that
>>>> clearly or optional, or not.
>>>> >>>>>>
>>>> >>>>>> func newFoo(bar: Int) {
>>>> >>>>>> //...
>>>> >>>>>> }
>>>> >>>>>>
>>>> >>>>>> or
>>>> >>>>>>
>>>> >>>>>> func newFoo(bar: Int?) {
>>>> >>>>>> //...
>>>> >>>>>> }
>>>> >>>>>>
>>>> >>>>>> When we write a new function we know what we need in this case
>>>> and use optional params or not.
>>>> >>>>>>
>>>> >>>>>> So my proposal is remove force unwrapping(`!`) from function
>>>> signatures, cause it have no sense, and that confuse new users.
>>>> >>>>>>
>>>> >>>>>>
>>>> >>>>>>
>>>> >>>>> _______________________________________________
>>>> >>>>> swift-evolution mailing list
>>>> >>>>> swift-evolution at swift.org
>>>> >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> >>>>
>>>> >>>> _______________________________________________
>>>> >>>> swift-evolution mailing list
>>>> >>>> swift-evolution at swift.org
>>>> >>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> >>>
>>>> >>
>>>> >> _______________________________________________
>>>> >> swift-evolution mailing list
>>>> >> swift-evolution at swift.org
>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> >
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>> --
>>> -Saagar Jha
>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>> --
> -Saagar Jha
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> --
-Saagar Jha
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160629/4ba6db6f/attachment.html>


More information about the swift-evolution mailing list