<div dir="ltr">Jordan, I think the inspiration here might come from Ruby. I must admit that seeing that `Array.first` returns an optional, but Array#subscript raises a runtime error when the index is out of bounds threw me for a loop. In Ruby, both Array#first and Array.subscript return an optional.<div><br></div><div>If one of the original tenets of swift was to provide greater compile-time null-safety, which it definitely seems it was given the commendable emphasis on optionals being easy to use, then returning an optional would be a solid way to go about subscripting. Think of it this way: when I call a method with nullable return value, I am forced to deal with the fact that the method can fail at compile time. When I subscript an array, I am not forced to deal with it at compile time, and it will fail at runtime instead.</div><div><br></div><div>Nullable subscripting is a big departure from the way most modern languages do things and that is why I don&#39;t blame you for rejecting it. That said, it is a pleasant change in the way you think about subscripting.</div><div><br></div><div>As a closing thought, subscripting hashes returns an optional value. You might consider this a pretty big inconsistency with arrays. Let me flip your argument against optional array subscripting, for dictionaries: <span style="line-height:1.5"><b>When you are performing a subscript where the key is out of the key set, is it not a programmer error?</b></span></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Dec 14, 2015 at 4:54 PM Jordan Rose via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi, Daniel. Thanks for bringing this up. May I ask where you would use a &quot;safe&quot; subscript? When are you performing a subscript where the bounds being…um, out-of-bound…is not a programmer error?<br>
<br>
As for the second half of this, we deliberately decided to not make the subscript operator &quot;smart&quot; (handling negative indexes and such) because extra branches can do very bad things to performance, and because allowing negative indexes sometimes hide bugs. It&#39;s also not meaningful for collections whose indexes are not integers.<br>
<br>
Best,<br>
Jordan<br>
<br>
&gt; On Dec 14, 2015, at 12:52, Daniel Duan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; In CollectionType, a `Range` is accepted as the argument in a version of `subscript`, which returns a subsequence.<br>
&gt;<br>
&gt;    [1,2,3,4][2...3] // [3, 4]<br>
&gt;<br>
&gt; `subscript` raises a fatal error if the range is out of bound, which is really a side-effect from accessing an element with an out of bound index. This behavior forces users to check bounds beforehand. It has been serving us well.<br>
&gt;<br>
&gt; I propose adding a new interface where user can recover from/defer out of bound error in this context. Here are two potential approaches.<br>
&gt;<br>
&gt; Approach #1 is more conservative, we add a throwing version of `subscript`. It throws an error if the range is out of bound. We can give the range parameter a name for distinction, resulting usage would look like:<br>
&gt;<br>
&gt;    do {<br>
&gt;       let gimme = [1,2,3,4][safe: 2...4]<br>
&gt;    } catch {<br>
&gt;        recover()<br>
&gt;    }<br>
&gt;<br>
&gt; As an alternative, we can replace the original `subscript` with this version, breaking backward compatibilty.<br>
&gt;<br>
&gt; Apporoach #2 is a really sweet syntax sugar. We add a new subscript that accepts 2 arugments:<br>
&gt;<br>
&gt;    extension CollectionType where Self.Index: RandomAccessIndexType {<br>
&gt;        public subscript(start:Int?, end:Int?) -&gt; Self.SubSequence { ... }<br>
&gt;    }<br>
&gt;<br>
&gt; This version would make ANY combination of arugment safe by enabling a sematic similar to Python&#39;s slicing mechanism. Explanations come after these examples:<br>
&gt;<br>
&gt;    [0,1,2,3][1, -1]                    // [1, 2]<br>
&gt;    [&quot;H&quot;,&quot;e&quot;,&quot;l&quot;,&quot;l&quot;,&quot;o&quot;][-1000, nil]   // [&quot;H&quot;,&quot;e&quot;,&quot;l&quot;,&quot;l&quot;,&quot;o&quot;]<br>
&gt;    [1,2,3,4,5,6,7,8][1,5][2,3]         // [4]<br>
&gt;<br>
&gt; This should look familiar to Python users:<br>
&gt;<br>
&gt; * the access is always clamped in-bound. Interpret out-of-bound number as the boundary.  [1,2,3][0: 100] means [1,2,3][0: 2].<br>
&gt; * nil indicate the boundary itself. [1,2,3][0: nil] means [1,2,3][0: 2]<br>
&gt; * negative index counts from the end of the sequence. [1,2,3][-2, -1] means [1,2,3][(3-2), (3-1)]<br>
&gt;<br>
&gt; Admittedly, this syntax suger seems a little out-of-place in Swift :P<br>
&gt;<br>
&gt; Both approaches require just a little of work. As an example, here&#39;s one implementation of the 2nd: <a href="https://github.com/dduan/Lic/blob/master/Lic/Lic.swift" rel="noreferrer" target="_blank">https://github.com/dduan/Lic/blob/master/Lic/Lic.swift</a> (please ignore the extension for String, that&#39;d be in a separate proposal, if any).<br>
&gt;<br>
&gt;<br>
&gt; What do you think?<br>
&gt;<br>
&gt; - Daniel Duan<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>