<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jan 16, 2018, at 2:18 PM, Michael Ilseman via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">(Replying to both Eneko and George at once)</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">I wonder if it is worth considering (for lack of a better word)&nbsp;<span class="" style="color: rgb(149, 126, 53);">*</span><i class="">verbose</i><span class="" style="color: rgb(149, 126, 53);">*</span>&nbsp;regular expression for Swift.</div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></blockquote></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);"><br class=""></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">It is certainly worth thought; even if we don’t go down that path there’s lessons to pick up along the way. I believe “verbal expressions” is basically what you’re describing:<span class="Apple-converted-space">&nbsp;</span><a href="https://github.com/VerbalExpressions/SwiftVerbalExpressions" class="">https://github.com/VerbalExpressions/SwiftVerbalExpressions</a></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 16, 2018, at 11:24 AM, Eneko Alonso via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Thank you for the reply. The part I didn’t understand is if if giving names to the captured groups would be mandatory. Hopefully not.<div class=""><br class=""></div></div></div></blockquote><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="">Assuming we the user does not need names, the groups could be captures on an unlabeled tuple.</div><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div><div class=""><div class="">I mention this through use of ‘_’.</div><div class=""><br class=""></div><div class=""><ul class="" style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 0px; color: rgb(36, 41, 46); font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;; font-size: 16px;"><li class="" style="box-sizing: border-box; margin-top: 0.25em;">A construct like&nbsp;<code class="" style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0.4em; margin: 0px; background-color: rgba(27, 31, 35, 0.0470588); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">(let _ = \d+)</code>&nbsp;could produce an unlabeled tuple element.</li></ul></div><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"></div></blockquote></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Thinking about explicit capture names, etc., is all subject to change based on more investigation and playing around with examples. See my email exchange with John Holdsworth, where most names end up being redundant with destructuring at their only use site. That may have just been overly simplistic examples, but maybe not.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="">Digits could always be inferred to be numeric (Int) and they should always be “exact” (to match "\d"):</div><div class=""><br class=""></div><div class=""><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">let usPhoneNumber: Regex = (</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">.digits(3) + "-“).oneOrZero + .</span><font color="#4f8187" face="Menlo" class="" style="background-color: rgb(255, 255, 255);"><span class="" style="font-size: 11px;">digits(3) +&nbsp;“-“ +&nbsp;</span></font><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">.digits(4)</span></div><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">What if you want to match a sequence of digits that are too large to fit in an Int? For example, the market cap of any stock in the S&amp;P 500 would overflow Int on 32-bit platforms. Having the default represent a portion of the input (whether that be Substring or just a Range) is more faithful to the purposes of captures, which is matching parts of text. Explicitly specifying a type is syntax for passing the capture into an init that serves as both a capture-validator as well as a value constructor, which is really just yet another kind of Pattern. (This might be generalizable to use beyond regexes, but that’s a whole other digression.) This also aids discovery, as you know what type’s conformance to RegexSubmatchableiblewobble to check.</div><div class=""><br class=""></div><div class="">(Note that some way to get slices or ranges will always be important for things like case-insensitive matching: changing case can change the number of graphemes in a string).</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="">Personally, I like the `.optional` better than `.oneOrZero`:</div><div class=""><br class=""></div><div class=""><div class=""><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">let usPhoneNumber = Regex.optional(</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">.digits(3) + "-“) + .</span><font color="#4f8187" face="Menlo" class="" style="background-color: rgb(255, 255, 255);"><span class="" style="font-size: 11px;">digits(3) +&nbsp;“-“ +&nbsp;</span></font><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">.digits(4)</span></div></div><div class=""><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);"><br class=""></span></div><div class="">Would it be possible to support both condensed and extended syntax?&nbsp;</div><div class=""><br class=""></div><div class=""><div class=""><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">let usPhoneNumber = / (\d{</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">3} + "-“)? + (\d{</span><font color="#4f8187" face="Menlo" class="" style="background-color: rgb(255, 255, 255);"><span class="" style="font-size: 11px;">3}) +&nbsp;“-“ + (\</span></font><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">d{4}) /</span></div><div class=""><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);"><br class=""></span></div><div class="">Maybe only extended (verbose) syntax would support named groups?</div><div class=""><br class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">“\d” is just syntax for a built-in character class named “digit”. There will be some way to use a character class, whether built-in or user-defined, in a regex.</div><div class=""><br class=""></div><div class="">For example, in Perl 6, you can say “\d” or “&lt;digit&gt;”, both of which are equivalent. Shortcuts for some built-in character classes are convenient and leverage the collective understanding of regexes amongst developers, and I don’t think they cause harm.</div><br class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><div class="">Eneko</div></div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 16, 2018, at 10:01 AM, George Leontiev &lt;<a href="mailto:georgeleontiev@gmail.com" class="">georgeleontiev@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">@Eneko While it sure seems possible to specify the type, I think this would go against the salient point "If something’s worth capturing, it’s worth giving it a name.” Putting the name further away seems like a step backward.<div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(40, 43, 53); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: &quot;Helvetica Neue&quot;; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">I could imagine a slightly more succinct syntax where things like .numberFromDigits are replaced by protocol conformance of the bound type:</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: &quot;Helvetica Neue&quot;; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106); background-color: rgb(40, 43, 53);">extension Int: Regexable {</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106); background-color: rgb(40, 43, 53);">&nbsp; &nbsp; func baseRegex&lt;T&gt;() -&gt; Regex&lt;T, Int&gt;</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106); background-color: rgb(40, 43, 53);">}</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106); background-color: rgb(40, 43, 53);">let usPhoneNumber = (/let area: Int/.exactDigits(3) + "-").oneOrZero +</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106); background-color: rgb(40, 43, 53);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let routing: Int/.exactDigits(3) + "-" +</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106); background-color: rgb(40, 43, 53);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let local: Int/.exactDigits(4)</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: &quot;Helvetica Neue&quot;; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(40, 43, 53); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 13px; line-height: normal; font-family: &quot;Helvetica Neue&quot;; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">In this model, the&nbsp;<span class="" style="color: rgb(104, 135, 143);">`</span><span class="" style="font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(147, 201, 106);">//</span><span class="" style="color: rgb(104, 135, 143);">`</span>&nbsp;syntax will only be used for initial binding and swifty transformations will build the final regex.</div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 16, 2018, at 9:20 AM, Eneko Alonso via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Could it be possible to specify the regex type ahead avoiding having to specify the type of each captured group?<div class=""><br class=""></div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);"><font color="#4f8187" face="Menlo" class=""><span class="" style="font-size: 11px;">let usPhoneNumber</span></font><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">:&nbsp;</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">Regex&lt;UnicodeScalar,</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">&nbsp;</span><span class="" style="color: rgb(79, 129, 135); font-family: Menlo; font-size: 11px;">(area: Int?, routing: Int, local: Int)&gt;</span><span class="" style="font-size: 11px; color: rgb(79, 129, 135); font-family: Menlo;">&nbsp;= /</span></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);"><font color="#4f8187" face="Menlo" class=""><span class="" style="font-size: 11px;">&nbsp; (\d{3}?) -<br class="">&nbsp; (\d{3}) -<br class="">&nbsp; (\d{4}) /<br class=""></span></font><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);">“Verbose” alternative:</div></div></div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">let usPhoneNumber:&nbsp;Regex&lt;UnicodeScalar,&nbsp;(area: Int?, routing: Int, local: Int)&gt;&nbsp;= /&nbsp;</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; .optional(.numberFromDigits(.exactly(3)) + "-“) +</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; .numberFromDigits(.exactly(3)) + "-"</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; .numberFromDigits(.exactly(4)) /</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">print(type(of: usPhoneNumber)) // =&gt; Regex&lt;UnicodeScalar, (area: Int?, routing: Int, local: Int)&gt;</div></div><div class=""><br class=""><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Eneko</div><div class=""><br class=""></div><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 16, 2018, at 8:52 AM, George Leontiev via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">Thanks, Michael. This is very interesting!</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">I wonder if it is worth considering (for lack of a better word)&nbsp;<span class="" style="color: rgb(149, 126, 53);">*</span><i class="">verbose</i><span class="" style="color: rgb(149, 126, 53);">*</span>&nbsp;regular expression for Swift.</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">For instance, your example:</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">let usPhoneNumber = /</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; (let area: Int? &lt;- \d{3}?) -</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; (let routing: Int &lt;- \d{3}) -</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; (let local: Int &lt;- \d{4}) /</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">would become something like (strawman syntax):</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">let usPhoneNumber = /let area: Int? &lt;- .numberFromDigits(.exactly(3))/ + "-" +</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let routing: Int &lt;- .numberFromDigits(.exactly(3))/ + "-"</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let local: Int &lt;- .numberFromDigits(.exactly(4))/</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">With this format, I also noticed that your code wouldn't match "555-5555", only "-555-5555", so maybe it would end up being something like:</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">let usPhoneNumber = .optional(/let area: Int &lt;- .numberFromDigits(.exactly(3))/ + "-") +</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let routing: Int &lt;- .numberFromDigits(.exactly(3))/ + "-"</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let local: Int &lt;- .numberFromDigits(.exactly(4))/</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">Notice that&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">area</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;is initially a non-optional&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">Int</span><span class="" style="color: rgb(149, 126, 53);">`</span>, but becomes optional when transformed by the&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">optional</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;directive.</div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></blockquote><div class=""><br class=""></div><div class="">That is a good catch and illustrates some of the trappings of regexes and the need for pick the right syntax. BTW, when you say optional, does it mean the match didn’t happen or the capture-validation didn’t succeed? In this example, it seems like the inclusive-or of both.</div></div></div></blockquote><div><br class=""></div><div>Yes, it would be inclusive-or. This is a good example of your above point how capture-validation and matching can be conflated. I can’t immediately thing of a good way to make this explicit, but being able to do&nbsp;<span style="color: rgb(147, 201, 106); font-family: Menlo; background-color: rgb(40, 43, 53);" class="">/let area: Int/</span>&nbsp;to match “something that can decode to Int” feels very convenient.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">Other directives may be:</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">let decimal = /let beforeDecimalPoint: Int &lt;-- .numberFromDigits(.oneOrMore)/ +</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .optional("." + /let afterDecimalPoint: Int &lt;-- .numberFromDigits(.oneOrMore)/</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">In this world, the&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">/&lt;--/</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;format will only be used for explicit binding, and the rest will be inferred from generic&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">+</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;operators.</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">I also think it would be helpful if&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">Regex</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;was generic over all sequence types.</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">Going back to the phone example, this would looks something like:</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">let usPhoneNumber = .optional(/let area: Int &lt;- .numberFromDigits(.exactly(3))/ + "-") +</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let routing: Int &lt;- .numberFromDigits(.exactly(3))/ + "-"</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /let local: Int &lt;- .numberFromDigits(.exactly(4))/</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);">print(type(of: usPhoneNumber)) // =&gt; Regex&lt;UnicodeScalar, (area: Int?, routing: Int, local: Int)&gt;</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">```</div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; font-family: &quot;Helvetica Neue&quot;; background-color: rgb(255, 255, 255);">Note the addition of&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">UnicodeScalar</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;to the signature of&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">Regex</span><span class="" style="color: rgb(149, 126, 53);">`</span>. Other interesting signatures are&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">Regex&lt;JSONToken, JSONEnumeration&gt;</span><span class="" style="color: rgb(149, 126, 53);">`</span>&nbsp;or&nbsp;<span class="" style="color: rgb(149, 126, 53);">`</span><span class="" style="font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);">Regex&lt;HTTPRequestHeaderToken, HTTPRequestHeader&gt;</span><span class="" style="color: rgb(149, 126, 53);">`</span>. Building parsers becomes fun!</div><div class=""><br class=""></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></blockquote><div class=""><br class=""></div><div class="">I think I missed something. What does the `UnicodeScalar` type parameter do?</div></div></div></blockquote><div><br class=""></div><div>I was just commenting here that we may want to regex over non-strings. Regex&lt;UnicodeScalar, T&gt; would operate over strings (sequences of UnicodeScalar), but being able to create Regexes for arbitrary sequences (non-strings) may be useful as well.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="">- George</div><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2018, at 11:58 AM, Michael Ilseman via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hello, I just sent an email to swift-dev titled "State of String: ABI, Performance, Ergonomics, and You!” at&nbsp;<a href="https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20180108/006407.html" class="">https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20180108/006407.html</a>, whose gist can be found at&nbsp;<a href="https://gist.github.com/milseman/bb39ef7f170641ae52c13600a512782f" class="">https://gist.github.com/milseman/bb39ef7f170641ae52c13600a512782f</a>. I posted to swift-dev as much of the content is from an implementation perspective, but it also addresses many areas of potential evolution. Please refer to that email for details; here’s the recap from it:<br class=""><br class="">### Recap: Potential Additions for Swift 5<br class=""><br class="">* Some form of unmanaged or unsafe Strings, and corresponding APIs<br class="">* Exposing performance flags, and some way to request a scan to populate them<br class="">* API gaps<br class="">* Character and UnicodeScalar properties, such as isNewline<br class="">* Generalizing, and optimizing, String interpolation<br class="">* Regex literals, Regex type, and generalized pattern match destructuring<br class="">* Substitution APIs, in conjunction with Regexes.<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote><div class=""><br class=""></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></body></html>