It is a bad idea to have the compiler change the interpretation of a type without some hard and fast rules; the compiler’s interpretation of the optionality of your code will result in your code being legal or not.
In terms of solutions, I would prefer something similar to a guard statement that, rather than exiting, shadows a constant or variable with a non-optional equivalent type, e.g. shadow var today = today ?? NSDate() let timeInterval = today.timeIntervalSinceNow -DW On May 2, 2016, at 1:27 PM, Tod Cunningham via swift-evolution <[email protected]> wrote: > > "I wonder if we’re pushing down the road of convenience at the expense of > truth. The if/guard let syntax is clear that you’re getting a separate > reference or copy, but what you’re suggesting is hiding the reality from the > user for what I see as relatively little convenience." > > It just might be me trying to avoid using !, and especially avoid implicit > unwrapped options. While there is nothing wrong with the following code it > makes me very uncomfortable from a defensive programming point of view: > > today = today ?? NSDate() > let timeInterval = today!.timeIntervalSinceNow > > Some developer coming along and changing the code could easily introduce a > crash, such as by removing the default value. In the above example, such a > change wouldn’t introduce a compiler warning/error and the bug might not > reveal itself until a much later. > > Also using if-let or guard also doesn’t seem right, in this case, as it > should never fail: > > today = today ?? NSDate() // self.today changed! > if let today = today { > let timeInterval: NSTimeInterval = today!.timeIntervalSinceNow > } else { > assertFailure() > } > > Same issue with guard: > > today = today ?? NSDate() // self.today changed! > guard let today = today else { > assertFailure() > return // that should never happen > } > let timeInterval: NSTimeInterval = today!.timeIntervalSinceNow > > This introduces code that just gets in the way of the code’s meaning for > cases that should never happen. Yuck, there has to be a better way! > > - Tod > > > > From: > <[email protected]<mailto:[email protected]>> > on behalf of Rod Brown via swift-evolution > <[email protected]<mailto:[email protected]>> > Reply-To: Rod Brown > <[email protected]<mailto:[email protected]>> > Date: Sunday, May 1, 2016 at 1:25 AM > To: David Sweeris <[email protected]<mailto:[email protected]>> > Cc: Erica Sadun via swift-evolution > <[email protected]<mailto:[email protected]>> > Subject: Re: [swift-evolution] Auto Unwrapping Of Optionals > > > On 1 May 2016, at 3:00 PM, David Sweeris > <[email protected]<mailto:[email protected]>> wrote: > > On Apr 30, 2016, at 5:42 PM, Rod Brown > <[email protected]<mailto:[email protected]>> wrote: > > Re-sent for Swift Evolution. Response at end. > > On 1 May 2016, at 6:31 AM, David Sweeris > <[email protected]<mailto:[email protected]>> wrote: > I think your idea makes a lot more sense in respect to ensuring we don't have > as much magic. > > That said, I still wonder about the implications for thread safety etc. While > it isn't a focus of Swift 3, it's something to think about whether this > promotes a paradigm that cannot be supported in a threaded environment, > specifically accessing properties. > > The if-let paradigm is a lot stronger for this set of actions. It gains a > separate reference or copy to the internal value, and allows you to action it > safely. Should the property change in the meantime, it isn't relevant, > because you have you own reference/copy, and then you have the right to > re-set the property as required. > > This, however, would theoretically add in an invisible ! for you. This leaves > you unable to handle the situation should the variable have been changed by > another thread between your check and your subsequent action. > > Unless I'm missing something, I worry about the behaviour of such a "feature" > in a multithreaded environment. I think the previous "inout" idea actually > held a lot more weight in this regard - at least then you can act on the > copy, and have the change propagate to the main declaration, and overwrite > any changes made on another thread. > > I think it would have the same resiliency as if-let, since I was envisioning > this to just be syntactic sugar for a switch statement. That is, this: > if foo is .Result { //`foo` refers to foo's associated or raw value within > the following code block > //code block > } > would get rewritten to this, for enums with associated values: > switchfoo { > case .Result(let foo): //we get a local copy of `foo` (the associated value) > for the following code block > //code block > default: break > } > or this, for enums with raw values: > switchfoo { > case .Result: > let _foo = foo.rawValue //the compiler substitutes `_foo` for `foo` > //code block > default: break > } > > There’d have to be some more auto-generated code to copy assigned values back > into the original `foo`, but I don’t think it’d be hard to do. > > - Dave Sweeris > > > Ah yes, that makes sense. So how do you see the compiler dealing with the > assignment/access problem on structs? If you assign to foo, the compiler > assigns to both “_foo” and “foo”? > > I wonder if we’re pushing down the road of convenience at the expense of > truth. The if/guard let syntax is clear that you’re getting a separate > reference or copy, but what you’re suggesting is hiding the reality from the > user for what I see as relatively little convenience. > > This is not to say I don’t see the problem, or the convenience… I just wonder > if this might be going a little too far. > > - Rod > > _______________________________________________ > 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
