I did not realize that change occurred with `do {}`! That seems like it should be a regression, given that previously there was explicitly a fix-it to rewrite naked `{}` to `do {}`.<br><div class="gmail_quote"><div dir="ltr">On Sat, Jun 10, 2017 at 09:06 Gor Gyolchanyan &lt;<a href="mailto:gor@gyolchanyan.com">gor@gyolchanyan.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">Yeah, that&#39;s why I mentioned a big **if** at the end. I love the `do { }` construct or variable isolation purposes and logical grouping, but unfortunately, Swift 4 has made it a lot uglier, by making it an error in its current form:<div><br></div><div>do {</div><div><span class="m_-5457763926699264408Apple-tab-span" style="white-space:pre-wrap">        </span>let a = &quot;123&quot;</div><div><span class="m_-5457763926699264408Apple-tab-span" style="white-space:pre-wrap">        </span>print(a)</div><div>} // error: missing `while`, also use `repeat` instead</div><div><br></div><div>The workaround is to do this:</div><div><br></div><div>do {</div><div><span class="m_-5457763926699264408Apple-tab-span" style="white-space:pre-wrap">        </span>let a = &quot;123&quot;</div><div><span class="m_-5457763926699264408Apple-tab-span" style="white-space:pre-wrap">        </span>print(a)</div><div>};</div><div><br></div><div>It might seem like a little change, but this really really bugs me for some reason. I always felt like semicolons in Swift should never be mandatory and should only be used for writing multiple statements on the same line.</div><div><br></div><div>Overall, I agree that this isn&#39;t a big enough reason to change the syntax for. Let&#39;s just make the `do { }` great again instead.</div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><br><div><br><blockquote type="cite"><div>On Jun 10, 2017, at 3:33 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_-5457763926699264408Apple-interchange-newline"><div><div>_Every_ addition to the basic syntax of the language is, by definition, high cost. The bar for additions to the standard library is already very high; the bar for additions to control flow syntax would be extraordinarily high.<br><br>The proposed use case here is far from the original topic of repeat {} while, which is unique because the condition lexically follows the loop.</div><div><br></div><div>For those loops in Swift where it is possible to declare variables in the condition, these live in a magical middle scope that is intuitive to use but also an exception to the rule of thumb that scopes are surrounded by braces. As I wrote earlier, it is possible to manually create an analogous scope by surrounding any loop with do {}. Any addition to the language would have to be vastly superior to this currently possible alternative, and I seriously doubt it is possible to invent such a thing because anything shorter than the four letters in “do {}” would also obscure the existence of the middle scope being created.</div><div><br></div><div><br><div class="gmail_quote"><div>On Sat, Jun 10, 2017 at 08:05 Goffredo Marocchi via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>If it is low cost and people do not come up with regressions/high cost + negative impact scenarios then I would say go full steam ahead. It does address an annoying scenario.<br><br><div id="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877AppleMailSignature">Sent from my iPhone</div></div><div><div><br>On 10 Jun 2017, at 12:04, Gor Gyolchanyan &lt;<a href="mailto:gor@gyolchanyan.com" target="_blank">gor@gyolchanyan.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div>Not much, I think. The `where` clause already exists, conditional `let` and `var` binding already exists. It&#39;d take loosening up conditional binding rules a bit and expanding the lexical structure to include `let` and `var` bindings in `repeat`.<br><div><br><blockquote type="cite"><div>On Jun 10, 2017, at 2:01 PM, Goffredo Marocchi &lt;<a href="mailto:panajev@gmail.com" target="_blank">panajev@gmail.com</a>&gt; wrote:</div><br class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-interchange-newline"><div><div>Quite interesting :), what impact would it have on the compiler?<br><br><div>Sent from my iPhone</div><div><br>On 10 Jun 2017, at 11:46, Gor Gyolchanyan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div>I think a better way of achieving this would be to use the already existing `where` keyword in loops. The way it works right now is as follows:<div><br></div><div>let many = [1, 2, 3, 4, 5]</div><div>for each in many where each % 2 == 0 {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>print(&quot;found an even number: \(each)&quot;)</div><div>}</div><div><br></div><div>Unfortunately, unlike all other conditional scopes, `where` does not allow `let` and `var` bindings in it, so I&#39;d suggest we add ability to do that:</div><div><br></div><div>let many: [Int?] = [1, 2, nil, 3, 4, nil, 5]</div><div>for each in many where let number = each {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>print(&quot;found a non-nil number: \(number)&quot;)</div><div>}<div><br></div><div>Or, more interestingly:</div><div><br></div><div>for each in many where let number = each, number % 2 == 0 {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>print(&quot;found a non-nil even number: \(number)&quot;)</div><div>}</div><div><br></div><div>And in case of a while loop:</div><div><br></div><div>var optional: Int? = 1</div><div>while let nonoptional = optional {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>if nonoptional &gt;= 10 {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">                </span>optional = nil</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>}</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>optional = nonoptional + 1</div><div>}</div><div><br></div><div>But this is only for optional unpacking, so another addition would be to allow any `let` and `var` bindings in conditional scopes without them contributing to the condition itself:</div><div><br></div><div>while let a = 0, a &lt; 10 {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>a += 1</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>print(a)</div><div>}</div><div><br></div><div>And finally, allow these bindings in `repeat`:</div><div><br></div><div>repeat let a = 0 {</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>a += 1</div><div><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>print(0)</div><div>} while a &lt; 10</div><div><br></div><div>I think **if** the core team would consider this a worthwhile addition, this would be a less invasive and more intuitive way of achieving what you want.</div><div><br><blockquote type="cite"><div>On Jun 10, 2017, at 1:31 PM, Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-interchange-newline"><div><div style="word-wrap:break-word"><div>Not sure if my e-mail didn&#39;t go through or if discussion just fizzled out; one other benefit if we ever move to a proper message board is we might gain the ability to bump topics. Anyway, I&#39;ll resend my message just in case:</div><div><br></div><div><br></div><br><div><div>Just to add my thoughts, as I like the idea of adding the variables to the start somehow, but was wondering if might make sense to have a keyword such as &quot;using&quot;, but allow it on all block statements, like-so:</div><div><div style="word-wrap:break-word"><div><br></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>// Original use-case of repeat … while</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>repeat using (var i = 0) {</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">                </span>// Do something</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>} while (i &lt; 20)</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>// for … in demonstrating combination of using and where</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>for eachItem in theItems using (var i = 0) where (i &lt; 20) {</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">                </span>// Do something either until theItems run out or i reaches 20</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>// Standard while loop</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>while let eachItem = it.next() using (var i = 0) where (i &lt; 20) {</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">                </span>// As above, but with an iterator and a while loop and conditional binding to also stop on nil</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>// Closure with its own captured variable</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>let myClosure:(Int) -&gt; Int = using (var i = 0) { i += 1; return i * $0 }</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>// If statements as well</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>if somethingIsTrue() using (var i = 0) where (i &lt; 20) {</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">                </span>// Do something</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div><font face="Monaco"><br></font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>// Or even a do block; while it does nothing functionally new, I quite like it aesthetically</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>do using (var i = 0) {</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">                </span>// Do something</font></div><div><font face="Monaco"><span class="m_-5457763926699264408m_-6394219739602900901m_-5320062136514170877Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div><br></div><div>Unifying principle here is that anything created in the using clause belongs to the loop, conditional branch etc. only, but exists outside the block itself (thus persisting in the case of loops and closures). I quite like the possible interaction with where clauses here as a means to avoid simple inner conditionals as well.</div><div><br></div><div>Basically the two clauses can work nicely together to avoid some common inner and outer boilerplate, as well as reducing pollution from throwaway variables.</div><div><br></div><div>Only one I&#39;m a bit iffy on is the closure; I&#39;m trying to avoid declaring the captured variable externally, but I&#39;m not convinced that having using on its own is clear enough?</div><div><br></div><div>Anyway, just an idea!</div></div></div></div><br></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div><br></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></div></blockquote></div><br></div></blockquote></div>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">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>
</blockquote></div></div>
</div></blockquote></div><br></div></div></blockquote></div>