I thought about this too, and I think it would be convenient. It feels a bit 
like artificial intelligence though, and I'm not sure how easy it would be to 
implement this. It should be sharply defined what the compiler should infer and 
what not. This can be very hard.

For example, you write `print("Today is \(today)")`: should it print an 
Optional or should it print just the date, because it knows that it cannot be 
nil? I say it should print `.Optional(... 23:37)`. But what if it prints just 
the date? In this case `today` cannot be nil, so it would be safe to just print 
`23:37`. Now, I see the source code example for the first time. What thinking 
process do I have to go through to know if the variable is automatically 
unwrapped or not? I'll think "can this variable be nil at that place?" The 
compiler also thinks "can this variable be nil at that place?" Will the 
compiler and me always agree in this respect? Or do I have to think "Will the 
compiler think that the variable can be nil at this place? Can it decide that 
it can never be nil?"? In this case, the language user needs to have a mental 
model about what inferences the compiler is able to do, so the rules must be 
fixed and easily understandable. The model would probably be something along 
the lines of "NSDate() always returns a non-optional value, so `x ?? NSDate()` 
is non-optional too." But knowing that foo(3) will return a value because foo 
only returns nil if its argument is < 0 is probably out of scope, even if the 
foo-function is defined within the same source file and even if the `-O2` flag 
is turned on (because you don't want to have different semantics depending on 
how much optimization is turned on).

Therefore, I think it would be best to only apply implicit unwrapping in cases 
where the code would otherwise not compile.

E.g. now you have to write

    var x: Int? = someFunction()
    if(x == nil) { return 22 }
    return x!+2+(2*x!);

It should be possible to rewrite this as

    var x: Int? = someFunction()
    if(x == nil) { return 22 }
    return x+2+(2*x);

This should only work for variables defined within the same scope, so this 
should fail to compile:

    // type of self.foo is String
    if(self.foo == nil) { return 11 }
    // type of myFunc is String -> ()
    myFunc(self.foo)
  
because even though self.foo was non-nil 1 microsecond ago, it doesn't mean 
that it is non-nil now.

On the other hand, what happens if a variable is captured by a block? Do we 
know that the variable is not mutated from another thread? Should we disable 
all these rules as soon as there is a block somewhere that captures one of the 
variables and might mutate them?

I just started thinking... For all these reasons, I don't see how this is going 
to be implemented in a way that is consistent and that doesn't introduce all 
kinds of strange edge cases. And any solution should be comprehensible by a 
Swift-beginner IMHO. On the other hand, if I ever forget a "!" somewhere, and 
the compiler compiles it anyways because it knows that it is safe, I will not 
complain :)

-Michael

> Am 29.04.2016 um 16:37 schrieb Tod Cunningham via swift-evolution 
> <swift-evolution@swift.org>:
> 
> I'm new to the swift evolution community, but I wanted to toss an idea out 
> there to get some feedback on it. So here it goes...
> 
> Currently, if you assign a non-nil value to an optional and then want to 
> access that optional later, in the same context, you need to manually unwrap 
> the value.  This is usually done either by using "!" or by using something 
> like "if let" or guard.
> 
> What would it be like if the compiler could auto unwrap, in cases where in 
> knows the optional will have some value?  This would make the code "clean" 
> and still be safe.
> 
> This concept of Auto Unwrapping of Optionals is similar to Implicitly 
> Unwrapped Optionals, but is only applied when the compiler knows it is safe 
> to do so.
> 
> Take the following example:
> 
> class Test {
>    var today: NSDate? = nil
>    func test() {
>        today = today ?? NSDate()
>        print("Today is \(today)")   // Would be printed as an optional
>        let timeInterval: NSTimeInterval = today!.timeIntervalSinceNow  // 
> Requires ! or (if let) to unwrap
>        // ... do stuff with timeInterval ...
>    }
> }
> 
> With the above example, the compiler could known that today has a value after 
> it's set in the test method.  So why couldn't the compiler auto unwrap it 
> when accessed?  This would mean manual unwrapping would be unnecessary:
> 
> class Test {
>    var today: NSDate? = nil
>    func test() {
>        today = today ?? NSDate()
>        print("Today is \(today)")   // Would be printed as a value (not an 
> optional)
>        let timeInterval: NSTimeInterval = today.timeIntervalSinceNow  // No ! 
> required (auto unwrapped)
>        // ... do stuff with timeInterval ...
>    }
> }
> 
> If the value later gets set to an optional value, then it will no longer be 
> auto unwrapable :
> 
> class Test {
>    var today: NSDate? = nil
> 
>    func optionalDay() -> NSDate? {
>        return NSDate()
>    }
> 
>    func test() {
>        today = today ?? NSDate()
>        print("Today is \(today)")   // Would be printed as a value (not an 
> optional)
>        let timeInterval: NSTimeInterval = today.timeIntervalSinceNow    // No 
> ! required (auto unwrapped)
>        let timeInterval2: NSTimeInterval = today!.timeIntervalSinceNow  // 
> Explicit unwrapping would still be allowed
> 
>        // If today is assigned an optional value, we can no longer auto 
> unwrap it
>        today = optionalDay()
>        print("Today is \(today)")   // Would be printed as an optional
>        let timeInterval3: NSTimeInterval = today!.timeIntervalSinceNow  // 
> manual unwrapping would be required
>    }
> }
> 
> Note in the above example, explicit unwrapping would still be allow.  The 
> variable is still an optional.  This allows for existing code to remain 
> unchanged.
> 
> This change would encourage less use of forced unwrapping "!", generally 
> require the developer to write less code, and would maintain code safety.  On 
> the down side, it is performing some compiler “magic”.  It would be yet 
> another thing to explain when trying to introduce people to swift and 
> especially optionals.
> 
> What do you all think, would something like this be worth pursuing, what 
> other pluses or minus would this introduce, has something like this already 
> been discussed?
> 
> Thanks,
> Tod Cunningham
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to