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