On 29.06.2016 6:57, Chris Lattner via swift-evolution wrote:

On Jun 27, 2016, at 4:42 PM, Saagar Jha via swift-evolution
<[email protected] <mailto:[email protected]>> wrote:

Alright, I’ve written it up a proposal; you can find it here
<https://gist.github.com/saagarjha/f33fecd4576f40133b6469da942ef453>.
This is my first proposal (and anyways I’ve been told that I can be
unclear), so if you guys see anything that should be changed feel free to
let me know. Here it is inline:

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

As I understand, Saagar suggests to disallow T! for function parameters only. And allow only T or T?.

About the API, as I understand, the suggestion is to explicitly use guard:

func someAPIFunc(t: T?) {
guard let t = t else { fatalError("t==nil was not expected in someAPIFunc") }

    // code of function
    print(t) // `t` is not optional here
}

From one side this adds more boilerplate code for API functions, but from other - such function is very clear about the behavior in case of `nil` sent to such function. I.e. all is explicit and clear. With IUO it is not obvious what will be the behavior if `nil` will be sent to func. Personally I'm not sure if I'm +1 for this suggestion or -1.. Probably +1 because of more obvious behavior and the fact that we can have more descriptive error in case of `nil` in such function.

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


  Remove implicitly unwrapped optionals as function parameters

  * Proposal: SE-NNNN
    <x-msg://38/NNNN-remove-implicitly-unwrapped-function-parameters.md>
  * 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 considered


      Importing 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
<[email protected] <mailto:[email protected]>> 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
    <[email protected] <mailto:[email protected]>> 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
        publicclassNSOrderedSet : NSObject, NSCopying, NSMutableCopying,
        NSSecureCoding, NSFastEnumeration{

            publicvarcount: Int{ get }
            publicfuncobjectAtIndex(idx: Int) -> AnyObject?
            publicfuncindexOfObject(object: AnyObject?) -> Int
            publicinit()
            publicinit(objects: UnsafePointer<AnyObject?>, count cnt: Int)
            publicinit?(coder aDecoder: NSCoder?)
        }

        This doesn't make much sense - mostly objectAtIndex(_:).

        On Jun 27, 2016, at 8:35 PM, Saagar Jha <[email protected]
        <mailto:[email protected]>> 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 <[email protected]
        <mailto:[email protected]>> 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
            <[email protected] <mailto:[email protected]>> 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 <[email protected]
            <mailto:[email protected]>> 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
            <[email protected]
            <mailto:[email protected]>> 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 <[email protected]
            <mailto:[email protected]>> 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 <[email protected]
            <mailto:[email protected]>> 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
            >>>>> [email protected]
            <mailto:[email protected]>
            >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
            >>>>
            >>>> _______________________________________________
            >>>> swift-evolution mailing list
            >>>> [email protected]
            <mailto:[email protected]>
            >>>> https://lists.swift.org/mailman/listinfo/swift-evolution
            >>>
            >>
            >> _______________________________________________
            >> swift-evolution mailing list
            >> [email protected] <mailto:[email protected]>
            >> https://lists.swift.org/mailman/listinfo/swift-evolution
            >

            _______________________________________________
            swift-evolution mailing list
            [email protected] <mailto:[email protected]>
            https://lists.swift.org/mailman/listinfo/swift-evolution

        --
        -Saagar Jha

        _______________________________________________
        swift-evolution mailing list
        [email protected] <mailto:[email protected]>
        https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Saagar Jha
_______________________________________________
swift-evolution mailing list
[email protected] <mailto:[email protected]>
https://lists.swift.org/mailman/listinfo/swift-evolution



_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to