<div dir="ltr">I think that both of these are new types or, at the very least, protocols. If you are ok with using something other than subscript to access them, a protocol is actually the best bet, in my opinion. With these additions, Array acts as though it has *infinite* length and Dictionary acts as though it holds all members that inhabit the Dictionary.Key type.  That is significant difference in behavior.<div>TJ</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 16, 2016 at 8:16 PM, Maximilian Hünenberger <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div></div><div>While I like the idea of a default value I don&#39;t think that you need one as often.</div><div><br></div><div><br></div><div>On another thread (&quot;Optional safe subscripting for arrays&quot;) something similar is being discussed where</div><div><br></div><div>array[safe: 6]</div><div><br></div><div>returns Optionals and your proposal is very similar to</div><div><br></div><div><span style="background-color:rgba(255,255,255,0)">array[safe: 6] ?? defaultValue</span></div><div>// or probably rewriting this to</div><div>array[6, default: defaultValue]</div><div><br></div><div>So these two proposals/threads could be merged.</div><div><br></div><div><br></div><div>In case of (Python like) slices I&#39;m not sure whether the additional syntax pays off for its use.</div><div><br></div><div><br></div><div>Do you have any concrete plan how it could be implemented? As additional property/closure/DefaultProtocol?</div><div>I&#39;m in favor of a closure: () -&gt; Element</div><div>since it is like a generator where less weird behaviors can occur due to referencing classes. (Value types would work (almost) flawlessly with a stored property)</div><div><br></div><div><br></div><div>Another note: Could there be a more general way to use &quot;_&quot; as a language feature? So the proposal would be more likely to be accepted.</div><div><br></div><div><br></div><div>Best regards</div><div>- Maximilian</div><div><div class="h5"><div><br>Am 17.01.2016 um 00:37 schrieb Paul Ossenbruggen via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;:<br><br></div><blockquote type="cite"><div><div>This is a preliminary draft, looking for feedback, thanks. </div><div><b style="font-size:14px"><br></b></div><b style="font-size:14px">Introduction</b><br style="font-size:14px"><br>There are many cases where you don’t want to deal with an out of range lookup in a array or dictionary. There is quite a lot of boilerplate code to check the range and return a value. This proposal addresses that by making a concise way of providing a default value in an array or dictionary. You quickly and safely want to get the value from an array or dictionary but not have to write a bunch of checks. <div><br>Swift-evolution thread: derived from ternary discussion. <br><br><b style="font-size:14px">Motivation</b></div><div><b><br></b>There are many times when you want to map value to another, the range of input values is beyond the array index. Typically you have to write code like this;</div><div><br></div><div><span style="white-space:pre-wrap">        </span><font color="#7b219f">let</font> dayString = [<font color="#b51a00">“Sunday”</font>, <font color="#b51a00">“Monday”,</font> “<font color="#b51a00">Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”</font>]</div><div><span style="white-space:pre-wrap">        </span><font color="#9929bd">guard</font>  dayIndex &gt; 0 &amp;&amp; dayIndex &lt; col..count else {</div><div><span style="white-space:pre-wrap">                </span><font color="#9929bd">return</font><font color="#ff4013"> “invalid day&quot;</font></div><div><span style="white-space:pre-wrap">        </span>}</div><div>       dayString[dayIndex] </div><div><br></div><div>Or for a dictionary:</div><div><br></div><div><div><span style="white-space:pre-wrap">        </span><span style="color:rgb(123,33,159)">let</span> chineseNumber = [   “<font color="#d12f1b" face="PingFang SC">一” : “One”,</font> </div><div><font color="#b51a00"><span style="font-family:Menlo;color:rgb(209,47,27)"><span style="white-space:pre-wrap">                </span>     “</span><span style="line-height:normal;font-family:&#39;PingFang SC&#39;;color:rgb(209,47,27)">二</span>” : ”Two”,</font></div><div><span style="white-space:pre-wrap">                                        </span>      “<font color="#b51a00"><span style="color:rgb(209,47,27);font-family:&#39;PingFang SC&#39;">三</span>” : ”Three”</font>]</div><div><br></div><div><span style="white-space:pre-wrap">        </span><span style="color:rgb(153,41,189)">guard</span>  <span style="color:rgb(123,33,159)">let</span> englishString = englishString <font color="#61177c">else</font> {</div><div><span style="white-space:pre-wrap">                </span><span style="color:rgb(153,41,189)">return</span> “out of range&quot;</div><div><span style="white-space:pre-wrap">        </span>}</div><div><span style="white-space:pre-wrap">        </span><span style="color:rgb(153,41,189)">return</span> englishString </div><div><br></div></div><div>Currently dictionaries only produce “nil” if not found so you must handle an optional. </div><div><br><b style="font-size:14px">Proposed solution:</b></div><div><b style="font-size:14px"><br></b></div><div>There approach is to add default to the containers. </div><div style="font-size:15px"><br></div><div><b>Array:</b></div><div>There is a new syntax which, allows you to choose a default:</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><br></div><div><div><span style="color:rgb(123,33,159)">let</span> lookupDayOfWeek = [<font color="#b51a00">“Sunday”</font>, <font color="#b51a00">“Monday”,</font> “<font color="#b51a00">Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday” &lt;&gt;</font><font> </font><font color="#b51a00">“Invalid Day” </font>]</div></div><div><div><br></div></div><div><div>lookupDayOfWeek[1] -&gt; “Monday”</div></div><div><div>lookupDayOfWeek[9] -&gt; “Invalid Day”</div></div></blockquote><div><div><br></div><div>The <span style="color:rgb(181,26,0)">&lt;&gt;</span> which is less than greater than. for the else portion, it indicates outside the range of the array as in less than the minimum index and greater than the highest index. It also looks like a diamond when run together so it stands out to clearly show that it is the default case and won’t be confused with the main array. In all other ways the array behaves the same, if you want to get the default value you could do this:</div><div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">lookupDayOfWeek[ _ ] -&gt; “Invalid Day”</blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><br></blockquote></div></div><div>Iterating an array with a default would not include the default:</div><div><br></div><div><span style="white-space:pre-wrap">        </span><font color="#61177c">for</font> day <font color="#61177c">in</font> lookupDayOfWeek {</div><div><span style="white-space:pre-wrap">                </span>print(“Day \(day)”)</div><div><span style="white-space:pre-wrap">        </span>}</div><div><br></div><div>You would need to do this to get the default (see below for slices):</div><div><div><div><br></div><div><span style="white-space:pre-wrap">        </span><span style="color:rgb(97,23,124)">for</span> day <span style="color:rgb(97,23,124)">in</span> lookupDayOfWeek[:_] {</div><div><span style="white-space:pre-wrap">                </span>print(“Day \(day)”)</div><div><span style="white-space:pre-wrap">        </span>}</div></div><div><br></div><div>or this would put the default first:</div><div><br></div><div><div><div><span style="white-space:pre-wrap">        </span><span style="color:rgb(97,23,124)">for</span> day <span style="color:rgb(97,23,124)">in</span> lookupDayOfWeek[_:] {</div><div><span style="white-space:pre-wrap">                </span>print(“Day \(day)”)</div><div><span style="white-space:pre-wrap">        </span>}</div></div></div><div><br></div></div><div>Unless there is a better suggestion for this, as this relies on slices. </div><div><br></div><div>Likewise contains() and other operations would not include the default as a result. However, if you were to copy an array with a default it would travel with the array:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><span style="color:rgb(123,33,159)">let</span> myOtherArray = lookupDayOfWeek<div>print(myOtherArray[_])  -&gt; “Invalid Day”</div><div><br></div></blockquote>If we were to adopt slices it would be possible to copy just the main values like this (based upon python slice syntax, speculative because slice syntax is not yet defined. If it is;):<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span style="color:rgb(123,33,159)">let</span> myOtherArray = lookupDayOfWeek[:]</div></div><div><div>print(myOtherArray) -&gt; [<font>“Sunday”</font>, <font>“Monday”,</font> “<font>Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”] </font></div></div><div><div><br></div></div><div><div><span style="color:rgb(123,33,159)">let</span> myOtherArray = lookupDayOfWeek[:_]</div></div><div><div><div>print(myOtherArray -&gt; [<font>“Sunday”</font>, <font>“Monday”,</font> “<font>Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday” &lt;&gt; &quot;I</font>nvalid Day”]</div></div></div></blockquote><div><div><br></div><div><b>Dictionary:</b></div><div>For a dictionary, we use the _: to indicate none of the above, which is consistent with current dictionary syntax except that it adds the _ case..</div><div><div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span style="color:rgb(123,33,159)">let</span> chineseToEnglishNumber = [   “<font color="#d12f1b" face="PingFang SC">一&quot; : “One”,</font> </div></div><div><div><font color="#b51a00"><span style="font-family:Menlo;color:rgb(209,47,27)"><span style="white-space:pre-wrap">                </span>         “</span><span style="line-height:normal;font-family:&#39;PingFang SC&#39;;color:rgb(209,47,27)">二&quot;</span>: ”Two”,</font></div></div><div><div><span style="white-space:pre-wrap">                                </span>                      &quot;<font color="#b51a00"><span style="color:rgb(209,47,27);font-family:&#39;PingFang SC&#39;">三&quot;</span>: ”Three”,</font></div></div><div><div><span style="white-space:pre-wrap">                                </span>                        _:  “<font color="#e32400">Out of Range</font>” ]</div></div><div><div><br></div></div><div><div><font>print(chineseToEnglishNumber[</font> “<font color="#b51a00"><span style="color:rgb(209,47,27);font-family:&#39;PingFang SC&#39;">三</span>”</font><font>]) -&gt; “Three&quot;</font></div></div><div><div><font>print(chineseToEnglishNumber[“</font><font color="#d12f1b" face="PingFang SC">四”</font><font face="PingFang SC">])</font><font color="#d12f1b" face="PingFang SC"> </font><font face="PingFang SC">-&gt; “Out of Range”</font></div></div><div><div><font face="PingFang SC"><br></font></div></div></blockquote><div><div><font>This concisely represents what to do if none of the values are usable. No more if let clauses or guards. Diamond <span style="color:rgb(181,26,0)">&lt;&gt;</span> could be supported here too, but that is optional for this proposal. The dictionary would be handled pretty much as it is today but the underscore-colon lets you give a default. Similarly, you can access the default value by doing this.</font></div><div><font><br></font></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><div><font><font>print(chineseToEnglishNumber[_</font><font face="PingFang SC">])</font><font color="#d12f1b" face="PingFang SC"> </font><font face="PingFang SC">-&gt; “Out of Range</font></font><font face="PingFang SC">”</font></div></div></div><div><div><div><br></div></div></div><div><div><div>print(chineseToEnglishNumber.contains(“None”)) -&gt; would return false. </div></div></div><div><div><div>print(chineseToEnglishNumber) -&gt; [<font face="Helvetica Neue">&quot;</font><span style="color:rgb(209,47,27);font-family:&#39;PingFang SC&#39;">一</span><font face="Helvetica Neue">&quot;: &quot;2&quot;, &quot;</font><span style="color:rgb(209,47,27);font-family:&#39;PingFang SC&#39;">二</span><font face="Helvetica Neue">&quot;: &quot;1&quot;, &quot;</font><span style="color:rgb(209,47,27);font-family:&#39;PingFang SC&#39;">三</span><font face="Helvetica Neue">&quot;: “3” &lt;&gt; “</font> <span style="color:rgb(227,36,0)">Out of Range</span><font color="#e32400">”</font><font face="Helvetica Neue">]</font></div></div></div></blockquote><font face="Helvetica Neue"><div><font face="Helvetica Neue"><br></font></div>Copying the dictionary would include the default but </font><span style="font-family:&#39;Helvetica Neue&#39;">iterating it would not include the default: </span><div><div><font face="Helvetica Neue"><br></font></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span style="color:rgb(97,23,124)">for</span> number <span style="color:rgb(97,23,124)">in</span> chineseToEnglishNumber {</div></div><div><div><div><span style="white-space:pre-wrap">        </span></div></div></div><div><div><div>}</div></div></div></blockquote><div><br></div>to include it (this may need work):<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><span style="color:rgb(97,23,124)">for</span> number <span style="color:rgb(97,23,124)">in</span> chineseToEnglishNumber[:_] {</div></div><div><div><span style="white-space:pre-wrap">        </span></div></div><div><div>}</div></div></blockquote><div><br></div>since dictionaries are unordered it will not necessarily be at the end..<div><div><div><div><div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><br></div></blockquote><div><div><b style="font-size:14px">Alternatives considered</b></div><div><br></div><div><b>Other operators:</b></div><div>Tried single colon and double colon but did not stand out enough and colon might not work if we adopted slices. </div><div><br></div><div><b>Sets</b></div><div>Thought about sets but not sure that makes sense because you only test existence of a member usually, the following kind makes sense to a point:</div><div><span style="font-family:&#39;PingFang SC&#39;"><br></span></div></div></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><div><div><div><span style="font-family:&#39;PingFang SC&#39;">let set = Set(“A”, “B”, “C” &lt;&gt; “D”)</span></div></div></div></div></div><div><div><font face="PingFang SC">set.contains(“B”) -&gt; true</font></div></div><div><div><div><font face="PingFang SC">set.contains(“D”) -&gt; false</font></div></div></div><div><div><div><font face="PingFang SC">set.contains(“F”) -&gt; false</font></div></div></div><div><div><font face="PingFang SC"><br></font></div></div><div><div><font face="PingFang SC">print(set) -&gt; [“A”, “B”, “C”]</font></div></div><div><div><font face="PingFang SC"><br></font></div></div></blockquote><div><div><font face="PingFang SC">but typically you are just checking for existence or getting all values so having it return a default does not make sense. </font></div><div><font face="PingFang SC"><br></font></div><div><font face="PingFang SC"><b>Map</b></font></div><div>This came out of the ternary and switch discussions, this could be done with map defaults. If we don’t want to add it to the container types that might be a better way to go. See that thread for more details. </div><div><br></div><div><font face="PingFang SC"><br></font></div><div><br></div></div></div></blockquote></div></div><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div><br>_______________________________________________<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/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>