<div dir="ltr">You could implement Range like below. So that range[i] = first + i * stride. This makes Range play nice with floats and other non-exact quantities.<div><br></div><div>







<p class=""><span class="">/// Provide the capabilities needed to impliment Range.</span></p>
<p class=""><span class="">/// Ranges are indexed with an Int index between 0 and count - 1 inclusive and they return start + index * stride, where start and stride are Rangees.</span></p>
<p class=""><span class="">/// Via extensions Int and Double are Rangees.</span></p>
<p class=""><span class="">protocol</span><span class=""> Rangee {</span></p>
<p class=""><span class="">    </span><span class="">/// self += rhs</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> add(rhs: </span><span class="">Self</span><span class="">)</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">/// self -= rhs</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> sub(rhs: </span><span class="">Self</span><span class="">)</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">/// self *= rhs</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> mult(rhs: </span><span class="">Self</span><span class="">)</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">/// self /= rhs</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> div(rhs: </span><span class="">Self</span><span class="">)</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">/// Converts to an Int, truncating towards 0 if necessary</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> toInt: </span><span class="">Int</span><span class=""> { </span><span class="">get</span><span class=""> }</span></p>
<p class=""><span class="">    </span></p>
<p class=""><span class="">    </span><span class="">/// Convert from an int, fails if the int is not representable</span></p>
<p class=""><span class="">    </span><span class="">static</span><span class=""> </span><span class="">func</span><span class=""> fromInt(i: </span><span class="">Int</span><span class="">) -&gt; </span><span class="">Self</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">// Make Int a Rangee</span></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">Int</span><span class="">: </span><span class="">Rangee</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> add(rhs: </span><span class="">Int</span><span class="">) { </span><span class="">self</span><span class=""> += rhs }</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> sub(rhs: </span><span class="">Int</span><span class="">) { </span><span class="">self</span><span class=""> -= rhs }</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> mult(rhs: </span><span class="">Int</span><span class="">) { </span><span class="">self</span><span class=""> *= rhs }</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> div(rhs: </span><span class="">Int</span><span class="">) { </span><span class="">self</span><span class=""> /= rhs }</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> toInt: </span><span class="">Int</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">self</span><span class=""> }</span></p>
<p class=""><span class="">    </span><span class="">static</span><span class=""> </span><span class="">func</span><span class=""> fromInt(i: </span><span class="">Int</span><span class="">) -&gt; </span><span class="">Int</span><span class=""> { </span><span class="">return</span><span class=""> i }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">// Make Double a Rangee</span></p>
<p class=""><span class="">extension</span><span class=""> </span><span class="">Double</span><span class="">: </span><span class="">Rangee</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> add(rhs: </span><span class="">Double</span><span class="">) { </span><span class="">self</span><span class=""> += rhs }</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> sub(rhs: </span><span class="">Double</span><span class="">) { </span><span class="">self</span><span class=""> -= rhs }</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> mult(rhs: </span><span class="">Double</span><span class="">) { </span><span class="">self</span><span class=""> *= rhs }</span></p>
<p class=""><span class="">    </span><span class="">mutating</span><span class=""> </span><span class="">func</span><span class=""> div(rhs: </span><span class="">Double</span><span class="">) { </span><span class="">self</span><span class=""> /= rhs }</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> toInt: </span><span class="">Int</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">Int</span><span class="">(</span><span class="">trunc</span><span class="">(</span><span class="">self</span><span class="">)) }</span></p>
<p class=""><span class="">    </span><span class="">static</span><span class=""> </span><span class="">func</span><span class=""> fromInt(i: </span><span class="">Int</span><span class="">) -&gt; </span><span class="">Double</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">Double</span><span class="">(i) }</span></p>
<p class=""><span class="">}</span></p>
<p class=""><span class=""></span><br></p>
<p class=""><span class="">/// An immutable-array-like collection that represents a potentially-inclusive range of Rangables such that `range[index] = first + index * stride`, where index in an Int between 0 and count - 1.</span></p>
<p class=""><span class="">/// `count = Int(trunc((last - first) / stride)) + 1`;</span></p>
<p class=""><span class="">/// therefore if `(last - first) / stride` is an integer, then the range includes last (or approximately last if underlying arithmetic type is non-exact).</span></p>
<p class=""><span class="">/// Name is MyRange to stop clash with Range, in practice woule be Range.</span></p>
<p class=""><span class="">struct</span><span class=""> MyRange&lt;R: Rangee&gt;: </span><span class="">CollectionType</span><span class=""> {</span></p>
<p class=""><span class="">    </span><span class="">let</span><span class=""> first: </span><span class="">R</span></p>
<p class=""><span class="">    </span><span class="">let</span><span class=""> last: </span><span class="">R</span></p>
<p class=""><span class="">    </span><span class="">let</span><span class=""> stride: </span><span class="">R</span></p>
<p class=""><span class="">    </span><span class="">let</span><span class=""> count: </span><span class="">Int</span></p>
<p class=""><span class="">    </span><span class="">init</span><span class="">(first: </span><span class="">R</span><span class="">, last: </span><span class="">R</span><span class="">, stride: </span><span class="">R</span><span class="">) {</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">first</span><span class=""> = first</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">last</span><span class=""> = last</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">stride</span><span class=""> = stride</span></p>
<p class=""><span class="">        </span><span class="">self</span><span class="">.</span><span class="">count</span><span class=""> = </span><span class="">MyRange</span><span class="">.</span><span class="">index</span><span class="">(first: first, stride: stride, of: last) + </span><span class="">1</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span><span class="">private</span><span class=""> </span><span class="">static</span><span class=""> </span><span class="">func</span><span class=""> index(first first: </span><span class="">R</span><span class="">, stride: </span><span class="">R</span><span class="">, of: </span><span class="">R</span><span class="">) -&gt; </span><span class="">Int</span><span class=""> {</span></p>
<p class=""><span class="">        </span><span class="">var</span><span class=""> index = of</span></p>
<p class=""><span class="">        index.</span><span class="">sub</span><span class="">(first)</span></p>
<p class=""><span class="">        index.</span><span class="">div</span><span class="">(stride)</span></p>
<p class=""><span class="">        </span><span class="">return</span><span class=""> index.</span><span class="">toInt</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">    </span><span class="">func</span><span class=""> index(of: </span><span class="">R</span><span class="">) -&gt; </span><span class="">Int</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">MyRange</span><span class="">.</span><span class="">index</span><span class="">(first: </span><span class="">first</span><span class="">, stride: </span><span class="">stride</span><span class="">, of: of) }</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> endIndex: </span><span class="">Int</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">count</span><span class=""> }</span></p>
<p class=""><span class="">    </span><span class="">var</span><span class=""> startIndex: </span><span class="">Int</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">0</span><span class=""> }</span></p>
<p class=""><span class="">    </span><span class="">// Note Range not MyRange needed for subscriptable range, in practice MyRange would be Range</span></p>
<p class=""><span class="">    </span><span class="">subscript</span><span class="">(bounds: </span><span class="">Range</span><span class="">&lt;</span><span class="">Int</span><span class="">&gt;) -&gt; </span><span class="">MyRange</span><span class="">&lt;</span><span class="">R</span><span class="">&gt; { </span><span class="">return</span><span class=""> </span><span class="">MyRange</span><span class="">(first: </span><span class="">self</span><span class="">[</span><span class="">bounds.</span><span class="">startIndex</span><span class="">]</span><span class="">, last: </span><span class="">self</span><span class="">[</span><span class="">bounds.</span><span class="">endIndex</span><span class=""> - </span><span class="">1</span><span class="">]</span><span class="">, stride: </span><span class="">self</span><span class="">.</span><span class="">stride</span><span class="">) }</span></p>
<p class=""><span class="">    </span><span class="">subscript</span><span class="">(index: </span><span class="">Int</span><span class="">) -&gt; </span><span class="">R</span><span class=""> {</span></p>
<p class=""><span class="">        </span><span class="">guard</span><span class=""> index &gt;= </span><span class="">0</span><span class=""> </span><span class="">else</span><span class=""> { </span><span class="">fatalError</span><span class="">(</span><span class="">&quot;Index, </span><span class="">\</span><span class="">(</span><span class="">index</span><span class="">), negative&quot;</span><span class="">) }</span></p>
<p class=""><span class="">        </span><span class="">guard</span><span class=""> index &lt; </span><span class="">count</span><span class=""> </span><span class="">else</span><span class=""> { </span><span class="">fatalError</span><span class="">(</span><span class="">&quot;Index, </span><span class="">\</span><span class="">(</span><span class="">index</span><span class="">), &gt;= count, </span><span class="">\</span><span class="">(</span><span class="">count</span><span class="">)&quot;</span><span class="">) }</span></p>
<p class=""><span class="">        </span><span class="">var</span><span class=""> result = </span><span class="">stride</span></p>
<p class=""><span class="">        result.</span><span class="">mult</span><span class="">(</span><span class="">R</span><span class="">.</span><span class="">fromInt</span><span class="">(index))</span></p>
<p class=""><span class="">        result.</span><span class="">add</span><span class="">(</span><span class="">first</span><span class="">)</span></p>
<p class=""><span class="">        </span><span class="">return</span><span class=""> result</span></p>
<p class=""><span class="">    }</span></p>
<p class=""><span class="">}</span></p></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature">  -- Howard.<br></div></div>
<br><div class="gmail_quote">On 29 March 2016 at 09:35, Erica Sadun 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><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
&gt; On Mar 28, 2016, at 3:54 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; on Mon Mar 28 2016, Erica Sadun &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt;&gt; On Mar 28, 2016, at 3:25 PM, Dave Abrahams via swift-evolution<br>
&gt;&gt;&gt; &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; on Mon Mar 28 2016, Xiaodi Wu<br>
&gt;&gt;<br>
&gt;&gt;&gt; &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
&gt;&gt;&gt; &lt;mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;&gt;<br>
&gt;&gt;&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Right, Countable could refine Strideable. I&#39;m no expert on this, but<br>
&gt;&gt;&gt;&gt; some cursory reading suggests that the analogous feature in C++ simply<br>
&gt;&gt;&gt;&gt; requires the type to have operator++ defined. Obviously, that won&#39;t<br>
&gt;&gt;&gt;&gt; work for Swift 3.0...<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hmm, instead of defining a new protocol (Countable), what if we just use<br>
&gt;&gt;&gt; “Strideable where Stride : Integer” as a constraint?<br>
&gt;&gt;<br>
&gt;&gt; I like a differentiation between continuous and discrete things<br>
&gt;&gt; although both can have ranges, membership, fences,<br>
&gt;&gt; and a way to stride through them<br>
&gt;<br>
&gt; Strideable where Stride : Integer expresses just exactly that.  Now if I<br>
&gt; could only get the type-checker to cooperate...<br>
<br>
</span>I am ridiculously excited about what you&#39;re doing there.<br>
Looking forward to beautiful floating point strides if for no<br>
other reason than I can point out how well they work for math<br>
in comparison to traditional for;;loops, so maybe people will<br>
stop burning semicolons on my lawn.<br>
<br>
What are you feelings about disjoint and invertible intervals?<br>
(I&#39;ll admit they currently fail the Lattner test[1], but they appeal to<br>
my aesthetics)<br>
<br>
-- E<br>
<br>
[1] First rule of Lattner: A language change should provide a highly focused<br>
tweak to Swift with limited impact and a measurable benefit to developers<br>
<div class="HOEnZb"><div class="h5"><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>
</div></div></blockquote></div><br></div>