<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 15, 2017, at 11:24 PM, John McCall via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 16, 2017, at 2:21 AM, Cao, Jiannan via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class="">Hi all,</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class="">I have come up an improvement point about Optional Chain Assignment</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class="">1. Optional Chain Assignment not working with tuple assignment</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class="">optional chain assignment only work for directly assignment, not working with tuple assignment.</div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">For example:</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><div style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px; margin: 0px; font-stretch: normal; line-height: normal;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="color: #ba2da2" class="">struct</span> ListNode {</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> <span style="color: #ba2da2" class="">var</span> next: <span style="color: #4f8187" class="">ListNode</span>?</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">}</div><div style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="color: #ba2da2" class="">var</span> previous: <span style="color: #4f8187" class="">ListNode</span>?</div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="color: #ba2da2" class="">var</span><span style="" class=""> current: </span>ListNode<span style="" class="">? = </span>ListNode<span style="" class="">()</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="" class="">//original version</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="" class="">let temp = </span>current?.next</div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class="">current<span style="" class="">?.next = </span>previous</div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class="">previous = current</div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class="">current = temp</div><div style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class="">// tuple assignment version (currently compiler error)</div></div></div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(79, 129, 135);" class=""><span style="" class="">(</span>current<span style="" class="">?.next, </span>previous<span style="" class="">, </span>current<span style="" class="">) = (</span>previous<span style="" class="">, </span>current<span style="" class="">, </span>current<span style="" class="">?.next)</span></div><div class=""><br class=""></div></div></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><b class="">error: cannot assign to immutable expression of type '_?'</b></div></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">(current?.next, previous, current) = (previous, current, current?.next)</b></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""> ~~~~~~~~~~~~~ ^</b></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class=""><br class=""></b></span></div></div></div></div></blockquote><div class="">Should we improve this situation?</div></div></div></blockquote><div class=""><br class=""></div>Optional chain assignment normally prevents the RHS of the assignment from being evaluated if the chain is aborted. What do you recommend as the semantics here? What if the optional element is later in the sequence?</div></div></div></blockquote><div><br class=""></div>I’m actually quite surprised by that behavior, and I consider this a gotcha I’ll have to keep in mind in the future. I would expect the rvalue calculation to execute, and if the lvalue ends up being nil it should just be ignored as if assigning to nil.property in objective C. <div class=""><br class=""></div><div class="">In particular, the following behavior is surprising to me:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="color: rgb(186, 45, 162);" class="">func</span> die<T>() -> <span style="color: rgb(79, 129, 135);" class="">T</span> { <span style="color: rgb(62, 30, 129);" class="">fatalError</span>() }</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="color: rgb(186, 45, 162);" class="">var</span> x: <span style="color: rgb(112, 61, 170);" class="">Int</span>? = <span style="color: rgb(186, 45, 162);" class="">nil</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: rgb(79, 129, 135);" class="">x</span><span style="color: rgb(0, 0, 0);" class=""> = </span><span style="color: rgb(49, 89, 93);" class="">die</span><span style="color: rgb(0, 0, 0);" class="">() </span>// Fatal trap, as expected</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal; color: rgb(186, 45, 162);" class="">class<span style="color: rgb(0, 0, 0);" class=""> C {</span></div><div style="margin: 0px; line-height: normal;" class=""> <span style="color: rgb(186, 45, 162);" class="">var</span> x: <span style="color: rgb(112, 61, 170);" class="">Int</span>? = <span style="color: rgb(186, 45, 162);" class="">nil</span></div><div style="margin: 0px; line-height: normal;" class="">}</div><div style="margin: 0px; line-height: normal;" class=""><span style="color: rgb(186, 45, 162);" class="">var</span> c: <span style="color: rgb(79, 129, 135);" class="">C</span>? = <span style="color: rgb(186, 45, 162);" class="">nil</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="color: rgb(79, 129, 135);" class="">c</span><span style="color: rgb(0, 0, 0);" class="">?.</span><span style="color: rgb(79, 129, 135);" class="">x</span><span style="color: rgb(0, 0, 0);" class=""> = </span><span style="color: rgb(49, 89, 93);" class="">die</span><span style="color: rgb(0, 0, 0);" class="">() </span>// No trap!?</div><div style="margin: 0px; line-height: normal; color: rgb(209, 47, 27);" class=""><span style="color: rgb(62, 30, 129);" class="">print</span><span style="color: rgb(0, 0, 0);" class="">(</span>"Still here"<span style="color: rgb(0, 0, 0);" class="">) </span><span style="color: rgb(0, 132, 0);" class="">// Executes</span></div><div class=""><span style="color: rgb(0, 132, 0);" class=""><br class=""></span></div></div></div><div class="">And similarly,</div></div><div class=""><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(186, 45, 162);" class=""><br class=""></span></div><div class=""><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(186, 45, 162);" class="">func</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> foo(</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(186, 45, 162);" class="">_</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> c: </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(79, 129, 135);" class="">C</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">?) -> </span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(112, 61, 170);" class="">Never</span><span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class=""> {</span></div><div class=""><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> c?.</span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">x</span><font face="Menlo" class=""><span style="font-size: 11px;" class=""> = </span></font><span style="font-family: Menlo; font-size: 11px; color: rgb(62, 30, 129);" class="">fatalError</span><span style="font-family: Menlo; font-size: 11px;" class="">()</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class="">Obviously this doesn’t compile right now because of the type mismatch [Int? <- Never], but once `Never` becomes the universal subtype the type theorists have been rooting for, I’d expect it to compile but never return. However, given your ignore-rvalues evaluation it would still not compile. “But I’m calling fatalError, how can it possibly return?”</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">John.</div></div>_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-dev<br class=""></div></blockquote></div><br class=""></body></html>