<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 Apr 17, 2017, at 10:40 PM, Douglas Gregor via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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=""><blockquote style="box-sizing: border-box; margin: 0px 0px 16px; padding: 0px 1em; border-left-width: 0.25em; border-left-style: solid; border-left-color: rgb(223, 226, 229); background-color: rgb(255, 255, 255);" class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px;" class=""><font color="#6a737d" face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol" size="3" class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md" class=""><br class="">https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md</a></font></div></blockquote><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">What is your evaluation of the proposal?</li></ul></div></div></blockquote>I really like the syntax and functionality. I especially like that it creates a protocol that all the various range types implement.</div><div><br class=""></div><div>Comments of varying quality:</div><div><br class=""></div><div>1. The following example at the start of the proposal does not compile, due both to index(where:) being inappropriate (I assume index(of:) was wanted?) , and index(where:) &nbsp;returning an optional:</div><div><pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12.600000381469727px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(36, 41, 46);" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> s <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Hello, World!<span class="pl-pds" style="box-sizing: border-box;">"</span></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> i <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> s.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">index</span>(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">where</span>: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>,<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> greeting <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> s[s.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">startIndex</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">..&lt;</span>i]</pre><div class=""><br class=""></div></div><div><div class="">I assume representing an optional as an input to a one-sided range is not intended - it would add complexity and likely mandate an AnyRangeExpression&lt;T&gt; type-erasing class. It is also more likely desirable for greeting to be nil in this case, rather than being an empty String.</div><div class=""><br class=""></div><div class="">It is probably appropriate instead to change the example. To avoid conditionals, I usually go with this syntax:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12.600000381469727px; margin-top: 0px; margin-bottom: 0px; font-stretch: normal; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(36, 41, 46);" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> s <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>Hello, World!<span class="pl-pds" style="box-sizing: border-box;">"</span></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> i <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> s.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">index</span>(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">where</span>: <span class="pl-s" style="box-sizing: border-box; color: rgb(24, 54, 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>,<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">let</span> greeting <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> i.map { s[s.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">startIndex</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">..&lt;$0</span>] }</pre><div class=""><br class=""></div></div><div class="">2. More on topic, RangeExpression is a protocol that all ranges implement, but appears to only be defined to be evaluated in the context of a collection and its collection indexes. Are there any other non-collection uses of this, such as intersecting two ranges (see point 5)?</div><div class=""><br class=""></div><div class="">3. As more of a general concern about Indexes and Comparable - RangeExpression has a `contains` method, raised I assume from the existing Range types and based on the Comparable index.</div><div class=""><br class=""></div><div class="">However, is it appropriate to evaluate collection indexes in this way, isolated from the collection itself? Today,types like DictionaryIndex will give arbitrary comparison results for indexes generated from two different dictionaries, but trap when methods like distance(from:to:) are called. This may be a bug in the case of DictionaryIndex, but it is not expected that indexes contain information about the collection they came from (such as Array, indexed by Int)</div><div class=""><br class=""></div><div class="">To ask as a more direct question: is it appropriate that an index may return true from RangeExpression contains, but causes a fatal error when used against the collection the RangeExpression index(es) came from?</div><div class=""><br class=""></div><div class="">4. As an extension to the third point, there appears to be a larger API surface of the Range types which could be exposed, such as overlaps() and clamped(to:). If contains() is appropriate for RangeExpression, would it make sense to include these, as well as possibly changing them to be expressed with RangeExpression arguemnts?</div><div class=""><br class=""></div><div class="">5. As a second extension to the third point, some languages have “creative” ranges which only make sense in the context of a collection. An example would be (from Ruby):</div><div class=""><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div class="">“Hello, World!”[-5...-1] # “World"</div></div></blockquote><div><div class=""><br class=""></div><div class="">where the negative index indicates an a negative distance from the end index.</div><div class=""><br class=""></div><div class="">Ignoring syntax bike shedding for the moment, such an expression could not be represented as a RangeExpression due to the inability to properly implement ‘contains’ in isolation of the collection to resolve proper indexes from these offsets.</div><div class=""><br class=""></div><div class="">There would still be ways to implement such behavior if desired by not having the type be a proper RangeExpression and extending Collection. The question is just meant to be another questioning of the relationship of RangeExpression to standalone ranges and to collections.</div><div class=""><br class=""></div><div class="">6. The proposal states:</div><div class=""><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div class=""><span style="color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The&nbsp;</span><code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(36, 41, 46);" class="">prefix</code><span style="color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">&nbsp;and&nbsp;</span><code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(36, 41, 46);" class="">suffix</code><span style="color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">&nbsp;methods that take an index&nbsp;</span><em style="box-sizing: border-box; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px;" class="">are</em><span style="color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">&nbsp;currently protocol requirements, but should not be. This proposal will fix that as a side-effect.</span></div></div></blockquote>and<font color="#24292e" face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol" size="3" class=""><br class=""></font><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div class=""><code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(36, 41, 46);" class="">prefix</code><span style="color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">&nbsp;and&nbsp;</span><code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(36, 41, 46);" class="">suffix</code><span style="color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">&nbsp;will be deprecated in Swift 4 and later removed.</span></div></div></blockquote><div class=""><br class=""></div>It seems removal of prefix and suffix methods from the Collection protocol is a breaking change in addition to removing prefix/suffix from Collection.&nbsp;<div class=""><br class=""></div><div class="">Would it be perhaps more desirable for Swift 4 to make prefix/suffix defined on an extension as well as deprecating them for removal in a later version of Swift? This could be done independent of whether this proposal is fully implemented/ships within Swift 4.<font color="#24292e" face="-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol" size="3" class=""><br class=""><br class=""></font><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Is the problem being addressed significant enough to warrant a change to Swift?</li></ul></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Does this proposal fit well with the feel and direction of Swift?</li></ul></div></div></blockquote>I think so. It will both create a more powerful collection indexing syntax and eliminate multiple functions on collection in the future. The syntax as well I believe is a good fit for the language.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box; margin-top: 0.25em;" class="">If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?</li></ul></div></div></blockquote>I’ve used ranged subscripts in ruby, and to a lesser degree python. Ruby in particular has more in-line functionality for expressing complex subsequence operations (such as negative integer indexes representing a negative offset from the endIndex).&nbsp;</div><div><br class=""></div><div>One fun part is that if RangeExpression is an exposed protocol, third parties can implement such extended functionality independent of the standard library (possibly included later if it works out to be highly used with a clear syntax winner.)</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><ul style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box; margin-top: 0.25em;" class="">How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</li></ul></div></div></blockquote>In-depth study<br class=""></div><div><br class=""></div><div>-DW</div><br class=""></div></body></html>