<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jun 8, 2016 at 1:58 PM, Tim Vermeulen <span dir="ltr">&lt;<a href="mailto:tvermeulen@me.com" target="_blank">tvermeulen@me.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That’s why I said “potentially less elegant”, some people might prefer `where` over `guard`. This proposal would give them the choice (in very specific situations) to use `where` rather than `guard` if they don’t want to sacrifice performance.<br></blockquote><div><br></div><div>Since Swift strives to be an opinionated language without dialects, there shouldn&#39;t be more &quot;choice&quot; but rather one general solution, IMO. Since `guard` doesn&#39;t sacrifice performance and is the most general, I would oppose adding the option of `while` to offer more choice.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
&gt; On Wed, Jun 8, 2016 at 1:35 PM, Tim Vermeulen via swift-evolution&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>(mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)&gt;wrote:<br>
&gt; &gt; This is a really strong argument in my opinion. If we don’t add a `while` to for loops, then in some situations we will have to rewrite a `where` clause to something potentially less elegant, given that we don’t want to give up performance.<br>
&gt; I disagree. I argue that what you call &quot;less elegant&quot;, namely if (or guard) inside the loop, is the most elegant solution.<br>
&gt;<br>
&gt; &gt;<br>
&gt; &gt; &gt;IMO `.prefix` is just not the equal alternative for as proposed `while` :<br>
&gt; &gt; &gt;in case of &#39;while&#39; expression `number&lt;4_000_000` will be calculated<br>
&gt; &gt; &gt;*only* for those who `number % 2 == 0`. In case of `prefix` - the<br>
&gt; &gt; &gt;expression will be processed for each `number` and only after this filtered<br>
&gt; &gt; &gt;by `number % 2`. Let&#39;s assume we need to check for some<br>
&gt; &gt; &gt;veryExpensiveTest(number):<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;for number in fibonacci where number % 2 == 0 while<br>
&gt; &gt; &gt;veryExpensiveTest(number) {}<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;let numbers = fibonacci.prefix { veryExpensiveTest($0) }<br>
&gt; &gt; &gt;for number in numbers where number % 2 == 0 {}<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;So, `while` for `for` loops just can&#39;t be always replaced with `prefix`<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;On 08.06.2016 2:02, Xiaodi Wu via swift-evolution wrote:<br>
</span>&gt; &gt; &gt;&gt;On Tue, Jun 7, 2016 at 5:11 PM, Tim Vermeulen&lt;<a href="mailto:tvermeulen@me.com">tvermeulen@me.com</a>(mailto:<a href="mailto:tvermeulen@me.com">tvermeulen@me.com</a>)<br>
<div><div class="h5">&gt; &gt; &gt;&gt;&lt;mailto:<a href="mailto:tvermeulen@me.com">tvermeulen@me.com</a>&gt;&gt;wrote:<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;I’ve been thinking about this for a bit now, and I think it would make<br>
&gt; &gt; &gt;&gt;most sense to evaluate these clauses from left to right. However, cases<br>
&gt; &gt; &gt;&gt;where the order matters are very uncommon, and I would rather have the<br>
&gt; &gt; &gt;&gt;power to choose which clause is evaluated first than to have a forced<br>
&gt; &gt; &gt;&gt;default order. Either way I don’t see this as a reason not to allow<br>
&gt; &gt; &gt;&gt;combining the two clauses because IMO it can lead to some very clean<br>
&gt; &gt; &gt;&gt;code. For instance, say we want to loop through all even fibonacci<br>
&gt; &gt; &gt;&gt;numbers below 4 million (see problem #2 from project euler), we could<br>
&gt; &gt; &gt;&gt;do this:<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;`for number in fibonacci where number % 2 == 0 while number&lt;4_000_000<br>
&gt; &gt; &gt;&gt;{ }`<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;This statement looks like spaghetti to me. I would not at all support<br>
&gt; &gt; &gt;&gt;extending the language to permit it. Do you really think it&#39;s more readable<br>
&gt; &gt; &gt;&gt;than going step-by-step?<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;```<br>
&gt; &gt; &gt;&gt;let numbers = fibonacci.prefix { $0&lt;4_000_000 }<br>
&gt; &gt; &gt;&gt;for number in numbers where number % 2 == 0 {<br>
&gt; &gt; &gt;&gt;// ...<br>
&gt; &gt; &gt;&gt;}<br>
&gt; &gt; &gt;&gt;```<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;or just:<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;```<br>
&gt; &gt; &gt;&gt;let numbers = fibonacci.prefix { $0&lt;4_000_000 }<br>
&gt; &gt; &gt;&gt;let evens = numbers.filter { $0 % 2 == 0 }<br>
&gt; &gt; &gt;&gt;for number in evens {<br>
&gt; &gt; &gt;&gt;// ...<br>
&gt; &gt; &gt;&gt;}<br>
&gt; &gt; &gt;&gt;```<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;I could have ordered the two clauses in any way I want. If combining<br>
&gt; &gt; &gt;&gt;the clauses weren’t allowed, I’d have to put (at least) one of them<br>
&gt; &gt; &gt;&gt;inside the block, which would be a (minor) pain.<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;I don’t currently have a very strong opinion about the order of<br>
&gt; &gt; &gt;&gt;evaluation, so I might be convinced otherwise. But combining the two<br>
&gt; &gt; &gt;&gt;clauses is so powerful that I don’t think it’s worth to get rid of just<br>
&gt; &gt; &gt;&gt;because of an edge case.<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;It may be workable if you can have only one or the other, but mixing and matching them as proposed above would be a world of hurt:<br>
&gt; &gt; &gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;```<br>
&gt; &gt; &gt;&gt;&gt;for foo in bar where condition1 while condition2 { ... }<br>
&gt; &gt; &gt;&gt;&gt;```<br>
&gt; &gt; &gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;If condition1 and condition2 both evaluate to true, then whether you continue or break would depend on the relative order of where and while; for generality, you would want to allow both `for...in...where...while` and `for...in...while...where`, and likely `for...in...while...where...while`, etc. There is nothing in the meaning of those words that would suggest that `while...where` behaves differently from `where...while`, etc. This is why words like &quot;break&quot; and &quot;continue&quot; are IMO far superior.<br>
&gt; &gt; &gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;<br>
</div></div>&gt; &gt; &gt;&gt;&gt;On Tue, Jun 7, 2016 at 2:34 PM, Erica Sadun&lt;<a href="mailto:erica@ericasadun.com">erica@ericasadun.com</a>(mailto:<a href="mailto:erica@ericasadun.com">erica@ericasadun.com</a>)<br>
<span class="">&gt; &gt; &gt;&gt;&lt;mailto:<a href="mailto:erica@ericasadun.com">erica@ericasadun.com</a>&gt;(mailto:<a href="mailto:erica@ericasadun.com">erica@ericasadun.com</a><br>
&gt; &gt; &gt;&gt;&lt;mailto:<a href="mailto:erica@ericasadun.com">erica@ericasadun.com</a>&gt;)&gt;wrote:<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
</span>&gt; &gt; &gt;&gt;&gt;&gt;&gt;On Jun 7, 2016, at 1:16 PM, Tim Vermeulen via swift-evolution&lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>(mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)<br>
<span class="">&gt; &gt; &gt;&gt;&lt;mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;(mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
&gt; &gt; &gt;&gt;&lt;mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;)&gt;wrote:<br>
&gt; &gt; &gt;&gt;&gt;&gt;&gt;&gt;The meaning of the proposed while is not at all a pair for where, since where clauses in while loops would do the same thing as while clauses in for loops. That&#39;s crazy.<br>
&gt; &gt; &gt;&gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;&gt;It sounds crazy, but it’s the nature of the while loop. A where clause in a while loop also has a different result than a where clause in a for loop.<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;The where_clause appears in the for in statement<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;for_in_statement : &#39;for&#39; &#39;case&#39;? pattern &#39;in&#39; expression where_clause? code_block<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;It&#39;s syntactic sugar because the expression can be already be limited through functional chaining of some sort or another. At the same time, it&#39;s nice and pleasant to have `where` and I&#39;m not itching to throw it out. The same courtesy could be easily extend to `when` (because I don&#39;t really want to use the `while` keyword here, but I could easily be convinced otherwise because I don&#39;t have a strong stance either way):<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;for_in_statement : &#39;for&#39; &#39;case&#39;? pattern &#39;in&#39; expression (where_clause | when_clause)? code_block<br>
&gt; &gt; &gt;&gt;&gt;&gt;when_clause : &#39;when&#39; expression<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;and again it could be nice and pleasant to have, although not necessary. The question comes down to how much does the language benefit by this sugar.<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;I&#39;d say that in both cases, combining chaining and statements is<br>
&gt; &gt; &gt;&gt;marginallyless goodthan either using standalone chaining or statements<br>
&gt; &gt; &gt;&gt;without chaining. But as I say this, I know as a fact, I fully intend<br>
&gt; &gt; &gt;&gt;to use `sequence(_:, next:).take(while:)` with for0in statements, so<br>
&gt; &gt; &gt;&gt;I&#39;m starting from a hypocritical vantage point.<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;To summarize, I&#39;m more +0.01 than I am -0.01 on this.<br>
&gt; &gt; &gt;&gt;&gt;&gt;<br>
&gt; &gt; &gt;&gt;&gt;&gt;-- E<br>
&gt; &gt; &gt;&gt;&gt;&gt;p.s. Sorry, wux<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;_______________________________________________<br>
&gt; &gt; &gt;&gt;swift-evolution mailing list<br>
</span>&gt; &gt; &gt;&gt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>(mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)<br>
<span class="">&gt; &gt; &gt;&gt;<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; swift-evolution mailing list<br>
</span>&gt; &gt; <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>(mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)<br>
&gt; &gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt;<br>
&gt;<br>
&gt; </blockquote></div><br></div></div>