<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Yeah, I definitely see your concerns about such code.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">That said, unless the compiler does a <i>lot </i>of rearranging under the covers, all you're asking he compiler to do is to hide the ! for you, which is something you should be aware of. If the compiler does the rearrangement, you're asking for two references or copies to be held while you do what you do. Additionally, the compiler could actually start doing so when your <i>don't </i>want it to. It could end up with another class of bugs where:</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">1. You assign to the variable</div><div id="AppleMailSignature">2. Another thread updates it</div><div id="AppleMailSignature">3. Later in the same method as the first assignment, you rely on that value being correct, but it's only a reference to the initial assignment, not truth.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Writing code that incorrectly states the truth about the value within a property to add safety will itself remove other types of safety.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">There are easy ways to handle the unsafe case you proposed that don't rely on this update, which is to assign to a local variable, update the property, and act on the local variable.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">let today: NSDate = self.today ?? NSDate()</div><div id="AppleMailSignature">let timeInterval = today.timeIntervalSinceNow</div><div id="AppleMailSignature"><span style="background-color: rgba(255, 255, 255, 0);">self.today = today</span></div><div id="AppleMailSignature"><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div id="AppleMailSignature">I think making the compiler rewrite your code in a way that changes the semantics of what you wrote to avoid this defensive programming technique ends up causing more problems than it solves. It would also make your code factually incorrect: you wouldn't be dealing with self.today, as your code would suggest, but a local reference (or copy in Swift 3).</div><div id="AppleMailSignature"><br></div><div><br>On 3 May 2016, at 5:27 AM, Tod Cunningham &lt;<a href="mailto:tcunningham@vectorform.com">tcunningham@vectorform.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span>"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’r suggesting is hiding the reality from the user for what I see as relatively little convenience."</span><br><span></span><br><span>It just might be me trying to avoid using !, and especially avoid implicit unwrapped options. &nbsp;While there is nothing wrong with the following code it makes me very uncomfortable from a defensive programming point of view:</span><br><span></span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;today = today ?? NSDate()</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let timeInterval = today!.timeIntervalSinceNow</span><br><span></span><br><span>Some developer coming along and changing the code could easily introduce a crash, such as by removing the default value. &nbsp;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.</span><br><span></span><br><span>Also using if-let or guard also doesn’t seem right, in this case, as it should never fail:</span><br><span></span><br><span> &nbsp;&nbsp;today = today ?? NSDate() &nbsp;&nbsp;// self.today changed!</span><br><span> &nbsp;&nbsp;if let today = today {</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let timeInterval: NSTimeInterval = today!.timeIntervalSinceNow</span><br><span> &nbsp;&nbsp;} else {</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFailure()</span><br><span> &nbsp;&nbsp;}</span><br><span></span><br><span>Same issue with guard:</span><br><span></span><br><span> &nbsp;&nbsp;today = today ?? NSDate() &nbsp;&nbsp;// self.today changed!</span><br><span> &nbsp;&nbsp;guard let today = today else {</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFailure()</span><br><span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return // &nbsp;that should never happen</span><br><span> &nbsp;&nbsp;}</span><br><span> &nbsp;&nbsp;let timeInterval: NSTimeInterval = today!.timeIntervalSinceNow</span><br><span></span><br><span>This introduces code that just gets in the way of the code’s meaning for cases that should never happen. &nbsp;Yuck, there has to be a better way!</span><br><span></span><br><span>- Tod</span><br><span></span><br><span></span><br><span></span><br><span>From: &lt;<a href="mailto:swift-evolution-bounces@swift.org">swift-evolution-bounces@swift.org</a>&lt;<a href="mailto:swift-evolution-bounces@swift.org">mailto:swift-evolution-bounces@swift.org</a>&gt;&gt; on behalf of Rod Brown via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&lt;<a href="mailto:swift-evolution@swift.org">mailto:swift-evolution@swift.org</a>&gt;&gt;</span><br><span>Reply-To: Rod Brown &lt;<a href="mailto:rodney.brown6@icloud.com">rodney.brown6@icloud.com</a>&lt;<a href="mailto:rodney.brown6@icloud.com">mailto:rodney.brown6@icloud.com</a>&gt;&gt;</span><br><span>Date: Sunday, May 1, 2016 at 1:25 AM</span><br><span>To: David Sweeris &lt;<a href="mailto:davesweeris@mac.com">davesweeris@mac.com</a>&lt;<a href="mailto:davesweeris@mac.com">mailto:davesweeris@mac.com</a>&gt;&gt;</span><br><span>Cc: Erica Sadun via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&lt;<a href="mailto:swift-evolution@swift.org">mailto:swift-evolution@swift.org</a>&gt;&gt;</span><br><span>Subject: Re: [swift-evolution] Auto Unwrapping Of Optionals</span><br><span></span><br><span></span><br><span>On 1 May 2016, at 3:00 PM, David Sweeris &lt;<a href="mailto:davesweeris@mac.com">davesweeris@mac.com</a>&lt;<a href="mailto:davesweeris@mac.com">mailto:davesweeris@mac.com</a>&gt;&gt; wrote:</span><br><span></span><br><span>On Apr 30, 2016, at 5:42 PM, Rod Brown &lt;<a href="mailto:rodney.brown6@icloud.com">rodney.brown6@icloud.com</a>&lt;<a href="mailto:rodney.brown6@icloud.com">mailto:rodney.brown6@icloud.com</a>&gt;&gt; wrote:</span><br><span></span><br><span>Re-sent for Swift Evolution. Response at end.</span><br><span></span><br><span>On 1 May 2016, at 6:31 AM, David Sweeris &lt;<a href="mailto:davesweeris@mac.com">davesweeris@mac.com</a>&lt;<a href="mailto:davesweeris@mac.com">mailto:davesweeris@mac.com</a>&gt;&gt; wrote:</span><br><span>I think your idea makes a lot more sense in respect to ensuring we don't have as much magic.</span><br><span></span><br><span>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.</span><br><span></span><br><span>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.</span><br><span></span><br><span>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.</span><br><span></span><br><span>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.</span><br><span></span><br><span>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:</span><br><span>if foo is .Result { //`foo` refers to foo's associated or raw value within the following code block</span><br><span> &nbsp;&nbsp;&nbsp;//code block</span><br><span>}</span><br><span>would get rewritten to this, for enums with associated values:</span><br><span>switchfoo {</span><br><span>case .Result(let foo): //we get a local copy of `foo` (the associated value) for the following code block</span><br><span> &nbsp;&nbsp;&nbsp;//code block</span><br><span>default: break</span><br><span>}</span><br><span>or this, for enums with raw values:</span><br><span>switchfoo {</span><br><span>case .Result:</span><br><span> &nbsp;&nbsp;&nbsp;let _foo = foo.rawValue //the compiler substitutes `_foo` for `foo`</span><br><span> &nbsp;&nbsp;&nbsp;//code block</span><br><span>default: break</span><br><span>}</span><br><span></span><br><span>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.</span><br><span></span><br><span>- Dave Sweeris</span><br><span></span><br><span></span><br><span>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”?</span><br><span></span><br><span>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.</span><br><span></span><br><span>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.</span><br><span></span><br><span>- Rod</span><br><span></span><br></div></blockquote></body></html>