<div dir="ltr">Thanks for the reply Dmitri - comments inline below:<div class="gmail_extra"><br clear="all"><div><div class="gmail_signature">  -- Howard.<br></div></div>
<br><div class="gmail_quote">On 9 February 2016 at 16:17, Dmitri Gribenko <span dir="ltr">&lt;<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</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="">On Mon, Feb 8, 2016 at 8:56 PM, Howard Lovatt via swift-users<br>
&lt;<a href="mailto:swift-users@swift.org">swift-users@swift.org</a>&gt; wrote:<br>
&gt; Hi,<br>
&gt;<br>
&gt; I think I have found a couple of bugs in lazy collections; just checking<br>
&gt; before filling. The following code is a filter map version of the Sieve of<br>
&gt; Eratosthenes:<br>
&gt;<br>
&gt; func lazyFilterMapForEachLoop(limit: Int = 9) -&gt; [Int] {<br>
&gt;<br>
&gt;     var possibles = Array(count: limit + 1, repeatedValue: true)<br>
&gt;<br>
&gt;     return (2 ... limit).lazy.filter { i in // Has to be lazy and sequential<br>
&gt; so that `possibles` is updated before it is used<br>
<br>
</span>Before looking at your questions below, I want to note that this is<br>
not a supported way of using the lazy subsystem.  The issue is that<br>
you seem to be relying on the evaluation order.  It is not guaranteed,<br>
even if you can reliably reproduce a certain evaluation order in the<br>
current version of the library.<br></blockquote><div><br></div><div>Not sure where it says that it won&#39;t be sequential - do you have a reference? </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
&gt; The filter closure is called twice per trial integer! First without<br>
&gt; preceding to the map stage at all, i.e. all values are filtered out! Second<br>
&gt; time through the numbers it does proceed to the map stage as you would<br>
&gt; expect.<br>
<br>
</span>Again, remember that you are using the *lazy* subsystem.  The<br>
evaluation order of the closures you are passing to the operations is<br>
not guaranteed.  Closures can be evaluated once, more than once, or<br>
not at all, and in the order that the library choses.  Closures are<br>
required to be pure, so you are not allowed to observe how many times<br>
and in which order they were actually evaluated.<br>
<br></blockquote><div>Not sure where it says it can be called more than one - the filter might be a very expensive operation like a database lookup!</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The reason why the closure is evaluated twice is because you end up<br>
calling an eager map(), which tries to reserve the array capacity<br>
suitable for the result.  To do that, map() calls &#39;count&#39; on the lazy<br>
filter collection, which triggers the computation the first time.<br>
<br></blockquote><div>map on a lazy collection results in another lazy collection, so I don&#39;t see this.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It is an open question though, whether calling the closure twice is<br>
profitable here, and what can we do about it.  The idea though is that<br>
those reallocations can sometimes be quite expensive when the closure<br>
is cheap to execute.  OTOH, when the closure is expensive to evaluate,<br>
calling it twice is a loss.<br>
<span class=""><br>
&gt; It produces an &quot;Index out of range&quot; error despite the fact that maximum<br>
&gt; number processed is 9 which is an allowable index of `possibles`.<br>
<br>
</span>Are you sure you didn&#39;t mean to use ..&lt; instead of ...?<br></blockquote><div><br></div><div>No I meant 2 ... limit, the array is of size limit + 1.</div><div><br></div><div>PS The equivalent code in Java works as expected. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
Dmitri<br>
<br>
--<br>
main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>
(j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>&gt;*/<br>
</font></span></blockquote></div><br></div></div>