<div dir="ltr">On Thu, Jan 19, 2017 at 4:35 PM, Joe Groff via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><span class="gmail-"><br>
&gt; On Jan 19, 2017, at 2:17 PM, Jonathan Hull via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt; Hi all,<br>
&gt;<br>
&gt; I would like to propose an optimization to the compiler where, when a call to an optional-returning function is immediately followed by a ‘!’, we allow the compiler to generate an alternate version of the function where a trap replaces &#39;return nil’ and the function returns a non-optional result.  This would save the build-up and tear-down cost of the optional.<br>
&gt;<br>
&gt; Is this possible?<br>
&gt;<br>
&gt;<br>
&gt; The main reason I would want this is to be able to later propose moving our default array index handling to a safer optional-returning version.  I know that a safe variant is on the horizon, but defaults really matter… especially with newcomers to the language.  Array indexing should return an optional, forcing the programmer to deal with an out-of-bounds case appropriately. Where the current behavior is desired, the access is immediately followed by a ‘!’ indicating the potential crash-point explicitly in code.  Migration would simply add a ‘!’ after every array subscript access. The above proposal is meant to mitigate any performance issues from the change, because the generated function for the cases followed by ‘!’ would be identical to the current version.<br>
&gt;<br>
&gt; It should also have a good effect on runtime performance for any place in code where a function result is immediately force unwrapped...<br>
<br>
</span>There are other reasons collection indexing doesn&#39;t return Optional besides performance; there have been a number of threads on this topic in the past already. I&#39;d be surprised if building an optional were really all that expensive to begin with—the binary representation of &#39;.some(x)&#39; inside an Optional is always the same as &#39;x&#39;, with at most a zero byte tacked on the end. Checking an optional in turn only needs to check for an invalid representation of x (like a null pointer) or check that that extra bit is unset.<br></blockquote><div><br></div><div>All other things being equal, it&#39;s hard to come out _against_ making code run faster.</div><div><br></div><div>But as Joe already touched on already, it&#39;s certainly not the case that indexing traps _only_ because of performance. This was touched on in the extensive discussions on &quot;lenient&quot; indexing. As here, some were calling that proposed feature &quot;safe&quot; indexing, and it was pointed out to them (by Dave A, I think?) that this use of the term &quot;safe&quot; misunderstands the kind of safety that Swift has prioritized. When you write `array[10]`, it&#39;s not saying &quot;I don&#39;t know how many elements there are, try and find the eleventh&quot;; it&#39;s saying &quot;I _know_ there are at least eleven elements, so get me that one.&quot;</div><div><br></div><div>When you _know_ that there are 11 elements, but in fact there are only 10, then something has gone badly wrong (because `array.count` doesn&#39;t lie). Trapping on a logic error is safe: an undefined state cannot do any more harm. Continuing on a logic error is unsafe. As Swift chooses safety by default, the default must be the current behavior.</div><div><br></div><div>For those times when you _don&#39;t_ know how many elements there are, don&#39;t care, and for some reason can&#39;t be bothered to get `array.count`, but you need to explicitly access an element by its index *and* have a useful fallback value, IMO it&#39;s reasonable to have an alternative subscript like the proposed `array[lenient: 10]`. But with facilities like `for...in`, `map`, etc., and others like `count` and `enumerated`, it&#39;s hard to argue that it&#39;s nearly as common a scenario as those where you are given a known-good index.</div><div><br></div><div>Alternatively, consider the effect of your proposed use case on a practical level. You have two arrays of known equal length and wish to swap every other element (this itself may be uncommon, but having two arrays and a task that involves both is, I&#39;m sure you&#39;ll agree, very common):</div><div><br></div><div>```</div><div>for i in stride(from: 0, to: a.count, by: 2) {</div><div>  swap(&amp;a[i], &amp;b[i])</div><div>}</div><div>```</div><div><br></div><div>Even with no performance penalty, it would look much uglier with:</div><div><br></div><div>```</div><div><div>for i in stride(from: 0, to: a.count, by: 2) {</div><div>  swap(&amp;a[i]!, &amp;b[i]!)</div><div>}<br></div></div><div><br></div><div><div>// Actually, would this even be possible? At first blush,</div><div>// it seems like it might not, since &amp;a[i] once unwrapped</div><div>// would have to be a _copy_ of the original, and a</div><div>// compiler optimization must not change the _semantics_</div><div>// of `!`, only its performance.</div></div><div>```</div><div><br></div><div>Littering `!` everywhere is not conducive to readable code.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
-Joe<br>
<div class="gmail-HOEnZb"><div class="gmail-h5">______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br></div></div>