<div dir="ltr"><div class="gmail_extra"><div><div class="gmail-m_-6246058590010182047gmail_signature"><div dir="ltr"><div><br></div></div></div></div><div class="gmail_quote">On Tue, Jan 3, 2017 at 10:10 AM, Joe Groff via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><span class="gmail-m_-6246058590010182047gmail-"><br><div><blockquote type="cite"><div>On Dec 22, 2016, at 7:43 PM, Robert Widmann &lt;<a href="mailto:devteam.codafi@gmail.com" target="_blank">devteam.codafi@gmail.com</a>&gt; wrote:</div><br class="gmail-m_-6246058590010182047gmail-m_-7132476344715227504Apple-interchange-newline"><div><div style="word-wrap:break-word"><div>Do you think there’s room for a more general <a href="https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms" target="_blank">Pattern Synonyms-like</a> feature that could extend this to things that look tuple-y?  We had a short conversation on Twitter &#39;round about the release of Swift 1.2 about Swiftz’s <a href="https://github.com/typelift/Swiftz/blob/master/Sources/HList.swift#L185" target="_blank">HList</a> implementation and my desire to be able to destructure them into tuples for native pattern matching.</div></div></div></blockquote><br></div></span><div>My personal favorite design for user-extensible pattern syntax is F#&#39;s &quot;active pattern&quot; feature, which lets you declare a set of mutual exclusive, total or partial conditions along with a function body that computes which condition holds. For the specific case of container patterns, though, I feel like it&#39;s worth keeping a close association with Collection semantics, so that:</div><div><br></div><div>- [] matches when the incoming collection&#39;s startIndex == endIndex,</div><div>- [&lt;pattern&gt;, &lt;pattern-list&gt;] fails if startIndex == endIndex, or else matches collection[startIndex] against &lt;pattern&gt; and recursively matches collection[startIndex.advanced<wbr>By(1)..&lt;endIndex] against [&lt;pattern-list&gt;]</div><div>- [&lt;pattern&gt;...] matches the remaining collection against &lt;pattern&gt;</div><div><br></div><div>-Joe</div></div></blockquote><div><br></div><div>This is really cool. I&#39;ve never used F#, so thanks for pointing this out. <a href="https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/active-patterns" target="_blank">https://docs.microsoft.<wbr>com/en-us/dotnet/articles/<wbr>fsharp/language-reference/<wbr>active-patterns</a>  Extra points for the name (| &quot;banana clips&quot; |).</div><div><br></div><div>I&#39;ve had something like this on my backburner-wishlist for a while. Customizable patterns/bindings could be very powerful.</div><div><br></div><div>One use case I had in mind: writing parsers for binary formats such as <a href="http://msgpack.org/index.html">msgpack</a>. For instance, msgpack encodes a uint16 as 0xcd + high byte + low byte. If the 0xcd could be given as a parameter to the &quot;active pattern&quot;, you could imagine writing something like</div><div><br></div><div>match msgpackStream {  // a raw byte stream</div><div><br></div><div>// Scan 3 bytes, the first of which is equal to 0xcd.</div><div>// Theoretical syntax allowing a custom stream-scanner object to fill in the two variable bindings</div><div>// by reading bytes from the stream. If the first byte were not 0xcd, the match would fail.</div><div>case [0xcd, let hi, let lo]:</div><div>    return UInt16(hi) &lt;&lt; 8 | UInt16(lo)</div><div>...</div><div>}</div><div><br></div></div></div></div>