<div dir="ltr">On Tue, Jun 7, 2016 at 6:26 PM, Tim Vermeulen <span dir="ltr">&lt;<a href="mailto:tvermeulen@me.com" target="_blank">tvermeulen@me.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Interesting. What if you put newlines before `where` and `while`? It’s hard to get the spacing right in a mailing list, but I tried it in Xcode and it looks really good to me (except for the compiler error it currently produces). Way better than the way I wrote it initially and the alternatives you mentioned.<br>
<span class=""><br>
for number in fibonacci<br>
    where number % 2 == 0<br>
    while number &lt; 4_000_000 { }<br></span></blockquote><div><br></div><div>This last line here is indistinguishable from the beginning of a while loop. I still think my examples above are superior, but even if you don&#39;t want to operate on the sequence beforehand, we can rewrite your multiline statement inside the loop in a crystal-clear way, no dollar signs or anything:</div><div><br></div><div>```</div><div>for number in fibonacci {</div><div>  if number % 2 != 0 { continue }</div><div>  if number &gt;= 4_000_000 { break }</div><div>}</div><div>```</div><div><br></div><div>Now the behavior is written out in full. It has the following advantages:</div><div><br></div><div>1) It is spelled out exactly what happens when a condition is met. I no longer have to remember whether the word that describes breaking from a loop uses a place analogy (&quot;where&quot;) or a time analogy (&quot;while&quot; or &quot;when&quot;).</div><div><br></div><div>(You cannot convince me that these words are intuitive when the meaning of &quot;where&quot; changes by context in today&#39;s Swift. Now, if you want to propose that these be named &quot;breakif&quot; and &quot;continueif&quot; instead, then I&#39;d agree with you that they&#39;re intuitive names, but then they&#39;d also be really ugly.)</div><div><br></div><div>2) It is absolutely clear which if statement gets evaluated first. Of course, we can make a rule for your proposed keyword, but there&#39;s no basis for assuming a priori that such a statement must be evaluated from left to right without consulting the Swift-specific rulebook. Take, for example, Python `foo if bar else boo`. By contrast, the if statements shown above are clearly evaluated one after the other and would be evaluated in the same order in every language under the sun.</div><div><br></div><div>3) I have the flexibility to do something between the first if statement and the second if statement, if I want. By placing the break statement at the end of my loop, I could effectively choose to have one more iteration than if I placed it at the beginning of my loop. There is nothing you can do to mimic that choice with your proposed while clause, unless you want to also propose a `for...in...repeat { } while` syntax.</div><div><br></div><div>4) This is the perhaps the important point. A beginning programmer--not any of us, presumably, but we were all beginners once--can accomplish everything that he or she desires without learning this new proposed syntax. Almost all texts, I believe, teach if statements before loops, and teach break and continue in the same breath as the loops themselves.</div><div><br></div><div>Each new piece of syntax is a challenge, and making connections between two equivalent facilities can be very, very hard. I&#39;ve witnessed truly brilliant people who are starting out to code throw up their hands in frustration because it feels unnecessarily cruel that they must learn several synonyms for the same concept. One of them asked me recently, &quot;If I can write i = i + 1, why would I ever write i += 1 or i++? There must be something special about ++, surely? Does it have any other uses?&quot; He concluded that he did not in fact understand assignment operators; I could not convince him that he understood them perfectly adequately.</div><div><br></div><div>Adding sugar for visual elegance carries this cost to the learner, and it is a real and non-trivial cost. Many beginners, I find, can accept that they&#39;ll read function names that they haven&#39;t heard of; after all, they can see that anyone can make a function named anything. But, a keyword or a core part of the language&#39;s syntax? Please appreciate that every addition there increases the learning curve for everyone.</div><div><br></div><div>Given that so many choices about how to write a loop are already available, you haven&#39;t convinced me that having another one brings tangible benefit to the language or to the code that I write. By contrast, I would cringe if I saw something like `for number in fibonacci where number % 2 == 0 while number&lt;4_000_000 { }` written on one line (and there is an understandable natural tendency to want to put a single statement all in one line). IMO, the Swifty way, with its emphasis on not having multiple &quot;dialects&quot; of the same language, would be to *decrease* the number of ways to write the same loop to one or a small number of well-considered, generally useful facilities. That&#39;s why I&#39;m in favor of cutting down on sugar rather than increasing it.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
<br>
</span>&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>)&gt;wrote:<br>
&gt; &gt; I’ve been thinking about this for a bit now, and I think it would make most sense to evaluate these clauses from left to right. However, cases where the order matters are very uncommon, and I would rather have the power to choose which clause is evaluated first than to have a forced default order. Either way I don’t see this as a reason not to allow combining the two clauses because IMO it can lead to some very clean code. For instance, say we want to loop through all even fibonacci numbers below 4 million(see problem #2 from project euler), we could do this:<br>
<span class="">&gt; &gt;<br>
&gt; &gt; `for number in fibonacci where number % 2 == 0 while number&lt;4_000_000 { }`<br>
&gt; This statement looks like spaghetti to me. I would not at all support extending the language to permit it. Do you really think it&#39;s more readable than going step-by-step?<br>
&gt;<br>
&gt; ```<br>
&gt; let numbers = fibonacci.prefix { $0&lt;4_000_000 }<br>
&gt; for number in numbers where number % 2 == 0 {<br>
&gt; // ...<br>
&gt; }<br>
&gt; ```<br>
&gt;<br>
&gt; or just:<br>
&gt;<br>
&gt; ```<br>
&gt; let numbers = fibonacci.prefix { $0&lt;4_000_000 }<br>
&gt; let evens = numbers.filter { $0 % 2 == 0 }<br>
&gt; for number in evens {<br>
&gt; // ...<br>
&gt; }<br>
&gt; ```<br>
&gt;<br>
&gt; &gt;<br>
&gt; &gt; I could have ordered the two clauses in any way I want. If combining the clauses weren’t allowed, I’d have to put (at least) one of them inside the block, which would be a (minor) pain.<br>
&gt; &gt;<br>
&gt; &gt; I don’t currently have a very strong opinion about the order of evaluation, so I might be convinced otherwise. But combining the two clauses is so powerful that I don’t think it’s worth to get rid of just because of an edge case.<br>
&gt; &gt;<br>
&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;<br>
&gt; &gt; &gt;```<br>
&gt; &gt; &gt;for foo in bar where condition1 while condition2 { ... }<br>
&gt; &gt; &gt;```<br>
&gt; &gt; &gt;<br>
&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;<br>
&gt; &gt; &gt;<br>
</span>&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>)(mailto:<a href="mailto:erica@ericasadun.com">erica@ericasadun.com</a>)&gt;wrote:<br>
<div class=""><div class="h5">&gt; &gt; &gt;&gt;<br>
&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>)(mailto:<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)&gt;wrote:<br>
&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;<br>
&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;<br>
&gt; &gt; &gt;&gt;The where_clause appears in the for in statement<br>
&gt; &gt; &gt;&gt;<br>
&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;<br>
&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;<br>
&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;when_clause : &#39;when&#39; expression<br>
&gt; &gt; &gt;&gt;<br>
&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;<br>
&gt; &gt; &gt;&gt;I&#39;d say that in both cases, combining chaining and statements is marginallyless goodthan either using standalone chaining or statements without chaining. But as I say this, I know as a fact, I fully intend to use `sequence(_:, next:).take(while:)` with for0in statements, so I&#39;m starting from a hypocritical vantage point.<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;To summarize, I&#39;m more +0.01 than I am -0.01 on this.<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;-- E<br>
&gt; &gt; &gt;&gt;p.s. Sorry, wux<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;<br>
&gt;<br>
&gt;<br>
&gt; </div></div></blockquote></div><br></div></div>