<div style="white-space:pre-wrap">Perhaps, but it is a much bigger change and a different proposal topic entirely. Given how variable declarations work now, Erica&#39;s proposed syntax to replace where clauses is the most elegant solution, IMO.<br></div><br><div class="gmail_quote"><div dir="ltr">On Sat, May 28, 2016 at 04:15 Goffredo Marocchi via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">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">This I would not cry about. In other languages they are more of a source of pain than anything else.<br>
<br>
Sent from my iPhone<br>
<br>
&gt; On 28 May 2016, at 09:10, David Hart via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt; Yet another alternative: would it be possible to disallow commas as variable declaration separators and use them for condition clause separators again:<br>
&gt;<br>
&gt; let a = 4, b = 8 // becomes illegal and requires to separate them on two lines<br>
&gt;<br>
&gt; if a &gt; 4, let c = foo(), let d = bar(), c != d { // now comma is not ambiguous anymore<br>
&gt; }<br>
&gt;<br>
&gt; David.<br>
&gt;<br>
&gt;&gt;&gt; On 28 May 2016, at 08:25, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Let me answer in another way that speaks to my background which isn&#39;t in compiler theory: The use of &amp;&amp; may produce cognitive overload between the use in Boolean assertions and the use in separating condition clauses.<br>
&gt;&gt;<br>
&gt;&gt; Yes, which is quite intentional on my part. The `if` statement requires that all of its clauses succeed; if pattern matching and optional testing were boolean expressions, you would use `&amp;&amp;` to link them with each other and with boolean tests. The fact that these are *not* boolean expressions is a mere artifact of Swift&#39;s implementation.<br>
&gt;&gt;<br>
&gt;&gt; I think our best solution is to make Swift act as though these *are* boolean expressions, but ones that can only be used in a limited way: they can only be `&amp;&amp;`ed, because they bind variables that have to be made available in specific blocks. In other words, I think we should paper over the compiler limitations preventing these things from working as expected.<br>
&gt;&gt;<br>
&gt;&gt; (Actually, it might be interesting to allow `!let` and `!case` statements which are available in the `else` branches of the control structures they&#39;re used in, but that&#39;s a different story...)<br>
&gt;&gt;<br>
&gt;&gt; ***<br>
&gt;&gt;<br>
&gt;&gt; If you&#39;ll permit me to go sort of &quot;mad dream&quot; here for a moment, I can actually sort of see a way to do a lot of this in the standard library. Imagine if the `let` and `case` clauses in a conditional produced a type like this:<br>
&gt;&gt;<br>
&gt;&gt;    enum PatternMatchingResult&lt;BoundValues&gt; {<br>
&gt;&gt;        case failed<br>
&gt;&gt;        case succeeded (BoundValues)<br>
&gt;&gt;    }<br>
&gt;&gt;<br>
&gt;&gt; `BoundValues` would be the values, if any, extracted through the pattern matching operation. Then you could define operators like these:<br>
&gt;&gt;<br>
&gt;&gt;    func &amp;&amp; &lt;T, U&gt;(lhs: PatternMatchingResult&lt;T&gt;, rhs: @autoclosure () -&gt; PatternMatchingResult&lt;U&gt;) -&gt; PatternMatchingResult&lt;(T, U)&gt; {<br>
&gt;&gt;        guard case .succeeded (let lhsValue) = lhs else {<br>
&gt;&gt;            return .failed<br>
&gt;&gt;        }<br>
&gt;&gt;        guard case .succeeded (let rhsValue) = rhs() else {<br>
&gt;&gt;            return .failed<br>
&gt;&gt;        }<br>
&gt;&gt;        return .succeeded (lhsValue, rhsValue)<br>
&gt;&gt;    }<br>
&gt;&gt;<br>
&gt;&gt;    func &amp;&amp; &lt;T&gt;(lhs: PatternMatchingResult&lt;T&gt;, rhs: @autoclosure () -&gt; Boolean) -&gt; PatternMatchingResult&lt;T&gt; {<br>
&gt;&gt;        guard case .succeeded = lhs else {<br>
&gt;&gt;            return .failed<br>
&gt;&gt;        }<br>
&gt;&gt;        guard rhs() else {<br>
&gt;&gt;            return .failed<br>
&gt;&gt;        }<br>
&gt;&gt;        return lhs<br>
&gt;&gt;    }<br>
&gt;&gt;<br>
&gt;&gt;    func &amp;&amp; &lt;U&gt;(lhs: Boolean, rhs: @autoclosure () -&gt; PatternMatchingResult&lt;U&gt;) -&gt; PatternMatchingResult&lt;U&gt; {<br>
&gt;&gt;        guard lhs else {<br>
&gt;&gt;            return .failed<br>
&gt;&gt;        }<br>
&gt;&gt;        return rhs()<br>
&gt;&gt;    }<br>
&gt;&gt;<br>
&gt;&gt; And then transform this:<br>
&gt;&gt;<br>
&gt;&gt;    guard<br>
&gt;&gt;        x == 0 &amp;&amp; a == b &amp;&amp; c == d &amp;&amp;<br>
&gt;&gt;        let y = optional, w = optional2, v = optional 3 &amp;&amp;<br>
&gt;&gt;        z == 2<br>
&gt;&gt;    else { ... }<br>
&gt;&gt;<br>
&gt;&gt; Into something like this (where `?` is a sort of &quot;anonymous capture slot&quot;):<br>
&gt;&gt;<br>
&gt;&gt;    guard case let .success (y, w, v) = (<br>
&gt;&gt;        x == 0 &amp;&amp; a == b &amp;&amp; c == d &amp;&amp;<br>
&gt;&gt;        Pattern(.some(?), .some(?), .some(?)).result(ofMatchingAgainst: (optional, optional2, optional3)) &amp;&amp;<br>
&gt;&gt;        z == 2<br>
&gt;&gt;    )<br>
&gt;&gt;    else { ... }<br>
&gt;&gt;<br>
&gt;&gt; Resolving to:<br>
&gt;&gt;<br>
&gt;&gt;    guard case let PatternMatchingResult.success (y, w, v) = (<br>
&gt;&gt;        (&amp;&amp;)(    // (Boolean, PatternMatchingResult) -&gt; PatternMatchingResult<br>
&gt;&gt;            x == 0,<br>
&gt;&gt;            (&amp;&amp;)(    // (Boolean, PatternMatchingResult) -&gt; PatternMatchingResult<br>
&gt;&gt;                a == b,<br>
&gt;&gt;                (&amp;&amp;)(    // (Boolean, PatternMatchingResult) -&gt; PatternMatchingResult<br>
&gt;&gt;                    c == d,<br>
&gt;&gt;                    (&amp;&amp;)(    // (PatternMatchingResult, Boolean) -&gt; PatternMatchingResult<br>
&gt;&gt;                        Pattern(.some(?), .some(?), .some(?)).result(ofMatchingAgainst: (optional, optional2, optional3)),<br>
&gt;&gt;                        z == 2<br>
&gt;&gt;                    )<br>
&gt;&gt;                )<br>
&gt;&gt;            )<br>
&gt;&gt;        )<br>
&gt;&gt;    )<br>
&gt;&gt;    else { ... }<br>
&gt;&gt;<br>
&gt;&gt; The `Pattern` type shown here is notional, not an actual thing that would exist as a first-class entity—although that *would* be rather nice to have eventually...<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; Brent Royal-Gordon<br>
&gt;&gt; Architechies<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; swift-evolution mailing list<br>
&gt;&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">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; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&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>
_______________________________________________<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>