<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Saagar Jha</div>

</div>
<div><br class=""><blockquote type="cite" class=""><div class="">On Dec 17, 2017, at 22:24, Nevin Brackett-Rozinsky via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">…well that was more complicated than I anticipated.<div class=""><br class=""></div><div class="">The “random” function was (Int) -&gt; Int, so when I removed the “IndexDistance == Int” constraint on “shuffle” I either had to add several “numericCast” calls or make “random” generic.</div><div class=""><br class=""></div><div class="">So I made “random” generic. And also fixed the modulo bias issue in the Glibc version that Saagar mentioned. Or at least I hope I did. I haven’t tested that part (nor any of the non-Swift-4 / non-macOS parts). Also, I am not sure why “random” had been a closure value stored in a “let” constant, but I changed it to a function.</div></div></div></blockquote><div><br class=""></div><div>Great! I'll close my pull request, then.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">While I was at it, I removed the random-access constraint I had placed on “shuffle”. It will now shuffle any MutableCollection, with complexity O(n) for a RandomAccessCollection and O(n²) otherwise. (The constraint was different in different Swift versions, so the entire extension had to be duplicated. Without the constraint the implementation is much sleeker.)</div><div class=""><br class=""></div><div class="">Nevin</div><div class=""><br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sun, Dec 17, 2017 at 9:26 PM, Nevin Brackett-Rozinsky <span dir="ltr" class="">&lt;<a href="mailto:nevin.brackettrozinsky@gmail.com" target="_blank" class="">nevin.brackettrozinsky@gmail.com</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class=""><div class="h5"><div class="gmail_extra"><div class="gmail_quote">On Sun, Dec 17, 2017 at 7:37 PM, Dave Abrahams <span dir="ltr" class="">&lt;<a href="mailto:dabrahams@apple.com" target="_blank" class="">dabrahams@apple.com</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""><blockquote type="cite" class=""><span class="m_-2884960459926388617gmail-"><div class="">On Dec 16, 2017, at 4:34 PM, Nevin Brackett-Rozinsky via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="m_-2884960459926388617gmail-m_2667904589485617490Apple-interchange-newline"></span><span class="m_-2884960459926388617gmail-"><div class=""><div style="font-family:HelveticaNeue;font-size:14px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><font face="monospace, monospace" class="">public extension MutableCollection&nbsp;where Self: RandomAccessCollection, IndexDistance == Int {</font></div></div></span></blockquote></div><br class=""><div class="">IndexDistance == Int is an over-constraint, FWIW.&nbsp; Adding it is generally a mistake.&nbsp; Not a serious one, but it does limit utility somewhat.</div><div class=""><br class=""></div><div class="">HTH,</div><div class="">Dave</div></div></blockquote></div><br class=""></div></div></div><div class="gmail_extra">You are correct, however there is an accepted-and-implemented proposal (<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0191-eliminate-indexdistance.md" target="_blank" class="">SE–0191</a>) to eliminate IndexDistance and replace it with Int, so the constraint will always be satisfied starting in Swift 4.1.</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">I wrote a version of shuffle() without that constraint, but it is less elegant: the line “for n in 0 ..&lt; count - 1” no longer compiles, and writing “0 as IndexDistance” doesn’t fix it because the resulting Range is not a Sequence, since IndexDistance.Stride does not conform to SignedInteger (at least in Swift 4.0 according to Xcode 9.2).</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">A while loop works of course, though a direct conversion requires writing “var n = 0 as IndexDistance” before the loop. Luckily, with a bit of cleverness we can eliminate all mention of IndexDistance, and this time we really and truly don’t need the “guard !isEmpty” line:</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra"><div class="gmail_extra"><font face="monospace, monospace" class="">extension MutableCollection&nbsp;where Self: RandomAccessCollection&nbsp;{</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; mutating func shuffle() {</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</font><span style="font-family:monospace,monospace" class="">var n = count</span></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp; while n &gt; 1 {</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let i = index(startIndex, offsetBy: count - n)</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let j = index(i, offsetBy: random(n))</font></div><div class="gmail_extra"><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n -= 1</span><font face="monospace, monospace" class=""><br class=""></font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; swapAt(i, j)</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">&nbsp; &nbsp; }</font></div><div class="gmail_extra"><font face="monospace, monospace" class="">}</font></div></div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Essentially, the constraint is there to make the code nicer on pre-4.1 versions of Swift, though I’m happy to remove it if you think that’s better. If nothing else, removing the constraint means people reading the example code in the future won’t be misled into thinking they need to use it themselves, so perhaps it should go just on that account.</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Okay, you’ve convinced me, I’ll update the PR. :-)</div><span class="HOEnZb"><font color="#888888" class=""><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Nevin</div></font></span></div>
</blockquote></div><br class=""></div></div>
_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></div></blockquote></div><br class=""></body></html>