# SE-0351: Regex Builder DSL

**URL:** <https://forums.swift.org/t/se-0351-regex-builder-dsl/56531>\
**Category:** Proposal Reviews\
**Created:** [April 5, 2022, 4:39am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531 "2022-04-05T04:39:58Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [April 5, 2022, 4:39am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/1 "2022-04-05T04:39:58Z")

</div>

Hello, Swift community.

The review of [SE-0351: Regex Builder DSL](https://github.com/apple/swift-evolution/blob/main/proposals/0351-regex-builder.md) begins now and runs through April 18, 2022.

* * *

This review is part of a collection of proposals for better string processing in Swift. The proposal authors have put together a [proposal overview](https://github.com/apple/swift-experimental-string-processing/blob/main/Documentation/Evolution/ProposalOverview.md) with links to in-progress pitches and reviews. This proposal builds on the `Regex` type [being reviewed](https://forums.swift.org/t/se-0350-regex-type-and-overview/56530)_simultaneously_ with this one, and is one of the proposed ways of creating such a type.

As with the concurrency initiative last year, the core team acknowledges that reviewing a large number of interlinked proposals can be challenging. In particular, acceptance of one of the proposals should be considered provisional on future discussions of follow-on proposals that are closely related but have not yet completed the evolution review process. Similarly, reviewers should hold back on in-depth discussion of a subject of an upcoming review. Please do your best to review each proposal on its own merits, while still understanding its relationship to the larger feature.

* * *

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the [review manager](mailto:ben_cohen@apple.com). If you do email me directly, please put "SE-0351" somewhere in the subject line.

## What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

- What is your evaluation of the proposal?
- Is the problem being addressed significant enough to warrant a change to Swift?
- Does this proposal fit well with the feel and direction of Swift?
- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at:

> [https://github.com/apple/swift-evolution/blob/main/process.md](https://github.com/apple/swift-evolution/blob/main/process.md)

As always, thank you for contributing to Swift.

Ben Cohen

Review Manager

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [April 5, 2022, 5:09am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/2 "2022-04-05T05:09:28Z")

</div>

Is `.eagerly` the right default for quantification, rather than `.possessively`? It's well known that eager quantification can be a performance footgun in regex engines when the expression doesn't match, to the point of being considered a DoS vulnerability. The improved composability of this syntax, and particularly the ability to progressively fold results into a well-typed tree, seems to encourage using this in more situations where the performance matters. Traditional regular expressions default to eager quantification, and matching those semantics for that syntax is important for people migrating regular expressions from other languages and APIs. But this syntax requires the regular expression to be completely rewritten, so it seems to me that we have an opportunity for a better default.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [April 5, 2022, 5:55am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/3 "2022-04-05T05:55:10Z")

</div>

Also, can you discuss generally where (if anywhere) this falls short of combinator parsing? The knot-tying you can do with the special `Regex` constructor seems to allow fairly general parsing.

---

<div class="post-metadata">

**Author:** ![smuroftfiws](https://avatars.discourse-cdn.com/v4/letter/s/f1d935/32.png) [@smuroftfiws](https://forums.swift.org/u/smuroftfiws)\
**Post date:** [April 5, 2022, 6:11am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/4 "2022-04-05T06:11:30Z")

</div>

Please, could you explain what does DSL mean?

Apart from that I think the proposal is excellent. Finally a readable syntax for regexes. Long live Swift.

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [April 5, 2022, 6:15am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/5 "2022-04-05T06:15:47Z")

</div>

> [@smuroftfiws](#):
>
> Please, could you explain what does DSL mean?

DSL stands for [_domain-specific language_](https://en.wikipedia.org/wiki/Domain-specific_language). Here's a related WWDC session: [write a DSL in Swift using result builders](https://developer.apple.com/videos/play/wwdc2021/10253/).

---

<div class="post-metadata">

**Author:** ![smuroftfiws](https://avatars.discourse-cdn.com/v4/letter/s/f1d935/32.png) [@smuroftfiws](https://forums.swift.org/u/smuroftfiws)\
**Post date:** [April 5, 2022, 6:32am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/6 "2022-04-05T06:32:54Z")

</div>

Thank you.

---

<div class="post-metadata">

**Author:** ![dlbuckley](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dlbuckley/32/14986_2.png) [@dlbuckley](https://forums.swift.org/u/dlbuckley)\
**Post date:** [April 5, 2022, 8:04am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/7 "2022-04-05T08:04:08Z")

</div>

I may have missed this; but if you use the DSL to build a regex could you output the raw regex from it? I'm thinking of scenarios where someone new to regex would use the DSL to build up their pattern and then they want to see the output to learn more about the underlying structure, or even someone more versed in regex themselves wanting to see the underlying raw regex for debugging/porting purposes.

---

<div class="post-metadata">

**Author:** ![AlexisQapa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alexisqapa/32/7159_2.png) [@AlexisQapa](https://forums.swift.org/u/AlexisQapa)\
**Post date:** [April 5, 2022, 9:47am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/8 "2022-04-05T09:47:02Z")

</div>

This could also be used to validate a regex after porting it to Swift by pasting the output into the original test suite.

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [April 6, 2022, 4:16pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/9 "2022-04-06T16:16:08Z")

</div>

Some minor discussion points below, that might not have been as obvious in context of the large proposal.

_edit: I didn't realize I was listed as an author, as such I've rephrased my questions as discussion points 😅_

* * *

```swift
// Parse the transaction kind.
  TryCapture {
    ChoiceOf {
      "CREDIT"
      "DEBIT"
    }
  } transform: {
    TransactionKind(rawValue: String($0))
  }

```

Any thoughts/bikeshedding for the `transform` label? Transform describes what it does, but it is a pretty generic term especially since the transform can fail producing a matching failure.

* * *

```swift
 OneOrMore(.custom([
      .characterClass(.word),
      .characterClass(.whitespace)
    ]))

```

Note that `.custom` and `.characterClass` are not proposed here, they are proposed in [Unicode for String Processing](https://github.com/apple/swift-experimental-string-processing/blob/main/Documentation/Evolution/ProposalOverview.md#unicode-for-string-processing).

* * *

```swift
    Repeat(.digit, count: 2)

```

Inside the detailed design, we see that the argument order is reversed for the resuilt-builder-taking variant, allowing something like

```swift
  Repeat(count: 2) { CharacterClass.digit }
  Repeat(2...2) { CharacterClass.digit }

```

* * *

> AlternationBuilder is a result builder type for creating alternations from components of a block.

Alternation is technically precise name for advanced library authors, and I don't feel that it has to use the exact same terminology as the end-user-facing `ChoiceOf`.

* * *

> With TryCapture, when the closure returns nil or throws, the failure becomes a no-match.

Clarification: a throw signals a pattern matching abort, meaning no backtracking to try alternatives. Returning `nil` will signal a local matching failure, backtracking to try alternatives.

* * *

> public subscript(\_ reference: Reference) -\> Capture { get }

More details: This will trap if a reference wasn't present in the regex. We can debate whether it should return `nil` in that case (like Dictionary, but would be obnoxious at the use site, potentially) or whether there should be API to query a reference. This becomes interesting when the definition and use site grow farther apart in source code and time.

* * *

```swift
extension Regex {
  public init<R: RegexComponent>(
    @RegexComponentBuilder _ content: (Regex<Substring>) -> R
  ) where R.Output == Match
}

```

```swift
Regex { wholeSentence in
  ChoiceOf {
   "I"
   "you"
  }
  "say"
  ChoiceOf {
    "goodbye"
    "hello"
    wholeSentence
  }
}

```

Does this impact type checking and error messages at all? Most important would be any impact on diagnostics for non-recursive regexes, since closures and especially result builders can give less-than-useful error messages. I'm wondering if the use of a label somewhere could help, especially since it's not super clear at the use site what the role of the `wholeSentence` parameter is.

* * *

> Support buildOptional and buildEither

Just to double check, we're not precluding ourselves from supporting builder-time `if` in the future. Parameterized regex construction could be very useful, but it totally makes sense to defer it as future work. There's a lot going on here as it is.

* * *

> Flatten optionals

Clarification: this behavior matches the literal typing behavior. We're interested in ways to flatten them in the future, no concrete plans at this moment.

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [April 6, 2022, 6:28pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/10 "2022-04-06T18:28:49Z")

</div>

> [@dlbuckley](#):
>
> if you use the DSL to build a regex could you output the raw regex from it?

I think it's a useful future direction! However, I wanted to clarify two things:

- `Regex`'s underlying representation is not the textual regex, but a general-purpose pattern matching program (for efficiency). So obtaining a textual regex from `Regex` would be a conversion.
- Not every `Regex` built with regex builder can be converted to a textual regex. Regex builder supports arbitrary types that conform to the `RegexComponent` protocol, including `CustomMatchingRegexComponent` (pitched in [regex-powered string processing algorithms](https://forums.swift.org/t/pitch-regex-powered-string-processing-algorithms/55969)) which can be implemented with arbitrary code. If a `Regex` contains a `CustomMatchingRegexComponent`, it cannot be converted to a textual regex.

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [April 6, 2022, 11:00pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/11 "2022-04-06T23:00:27Z")

</div>

> [@John\_McCall](#):
>
> Is `.eagerly` the right default for quantification, rather than `.possessively` ? It's well known that eager quantification can be a performance footgun in regex engines when the expression doesn't match, to the point of being considered a DoS vulnerability. The improved composability of this syntax, and particularly the ability to progressively fold results into a well-typed tree, seems to encourage using this in more situations where the performance matters. Traditional regular expressions default to eager quantification, and matching those semantics for that syntax is important for people migrating regular expressions from other languages and APIs. But this syntax requires the regular expression to be completely rewritten, so it seems to me that we have an opportunity for a better default.

As a bit of background, I was very strongly in favor of this approach initially. Attempts to make the Regex result builders behave like `Pattern<T>` (a type for parsers) increasingly created uncanny hybrids, and I've reversed my position for Regex specifically. A proper parser system needs more and deserves its own presentation, even if it's built on top of the same underlying capabilities here.

I think it's important to reduce the semantic divergence between the literals and result builders, and my main concern is that possessive-by-default creates a less understandable and less consistent system. This is especially the case if we only do it for quantification but keep global backtracking across subpatterns.

`x*+` is syntactic sugar for `(?>x*)`, that is wrapping the quantification in an atomic group. An atomic group establishes a local backtracking scope where, upon any successful exiting of that scope, all backtracking entries added within that scope are discarded. The result builder spelling of this is `Local`.

```swift
OneOrMore(..., .possessive)

Local { OneOrMore { ... } }

```

Personally I prefer the latter, as I feel it more directly and faithfully surfaces the semantics and seems an easier system to learn and teach. I could even see the argument to drop the quantification kind entirely from API in favor of `OneOrMore`, `MinimallyOneOrMore` (or some better name; these are fairly rare), and `Local { OneOrMore }`.

Future work can be a (names TBD) `ratchet` operation that will discard any backtracking entries since some prior ratchet point. These would be a lower-level formulation of `Local` that's suitable when needs transcend nesting. I.e. Local is akin to a pseudo-code `defer { ratchet }` at the top of the scope.

* * *

Possessive by default is most commonly found in grammar systems, where it's much easier to compose these linear-ish expressions and rules provide a fully local backtracking approach. There non-possessive can naturally desugar to `S -> x S | <empty>`.

I'm a big fan of possessive-by-default local-backtracking-only rules which are combined into a grammar. Unfortunately, we're not building a grammar system here (yet) and we're not claiming regex provides a full fledged parser combinator system (even if one can be forcibly wedged in via `CustomMatchingRegexComponent`). Regex could participate in such a system, but I'm wary of diverging fundamental concepts too much from what they mean within the world of regex.

What we're proposing is the regexiest regex, while still very much being a regex. Regex is inherently global backtracking by default with local backtracking opt-in; quantification is just a specific instance of this.

I realize that possessive-by-default is less strongly motivated by this line of reasoning than some of the capture representations, and I do hope it can be alleviated through API design. Ideally, I feel this would be best solved with a clear naming scheme, but my mind fails to find such a suitable scheme.

---

<div class="post-metadata">

**Author:** ![stevapple](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stevapple/32/31979_2.png) [@stevapple](https://forums.swift.org/u/stevapple)\
**Post date:** [April 7, 2022, 7:04am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/12 "2022-04-07T07:04:10Z")

</div>

> [@rxwei](#):
>
> Not every `Regex` built with regex builder can be converted to a textual regex. Regex builder supports arbitrary types that conform to the `RegexComponent` protocol, including `CustomMatchingRegexComponent` (pitched in [regex-powered string processing algorithms](https://forums.swift.org/t/pitch-regex-powered-string-processing-algorithms/55969)) which can be implemented with arbitrary code. If a `Regex` contains a `CustomMatchingRegexComponent` , it cannot be converted to a textual regex.

How about adding something like `func buildRegexString() -> String` to `RegexComponent`, allowing (and enforcing) every Regex component to have its own String representation? A `CustomMatchingRegexComponent` provider can choose its preferred spelling (or placeholder) for the component (or maybe leave it up to end-user through the initializer).

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [April 7, 2022, 7:21am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/13 "2022-04-07T07:21:16Z")

</div>

Conversion to textual regex is a possible future direction, but I think the functionality is purely additive and therefore is out of scope for this proposal.

I added a future direction section about this in [apple/swift-evolution#1612](https://github.com/apple/swift-evolution/pull/1612).

> ****
>
> ## Future directions
> 
> ### Conversion to textual regex
> 
> Sometimes it may be useful to convert a regex created using regex builder to textual regex. This may be achieved in the future by extending `RegexComponent` with a computed property.
> 
> ```swift
> extension RegexComponent {
> public func makeTextualRegex() -> String?
> }
> 
> ```
> 
> It is worth noting that the internal representation of a `Regex` is _not_ textual regex, but an efficient pattern matching bytecode compiled from an abstract syntax tree. Moreover, not every `Regex` can be converted to textual regex. Regex builder supports arbitrary types that conform to the `RegexComponent` protocol, including `CustomMatchingRegexComponent` (pitched in [String Processing Algorithms]) which can be implemented with arbitrary code. If a `Regex` contains a `CustomMatchingRegexComponent`, it cannot be converted to textual regex.

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [April 7, 2022, 9:12am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/14 "2022-04-07T09:12:54Z")

</div>

> [@Michael\_Ilseman](#):
>
> > public subscript(\_ reference: Reference) -\> Capture { get }
> 
> More details: This will trap if a reference wasn't present in the regex. We can debate whether it should return `nil` in that case (like Dictionary, but would be obnoxious at the use site, potentially) or whether there should be API to query a reference. This becomes interesting when the definition and use site grow farther apart in source code and time.

Clarified the precondition:

```swift
extension Regex.Match {
  /// Returns the capture referenced by the given reference.
  ///
  /// - Precondition: The reference must have been captured in the regex that produced this match.
  public subscript<Capture>(_ reference: Reference<Capture>) -> Capture { get }
}

```

> [@Michael\_Ilseman](#):
>
> Does this impact type checking and error messages at all? Most important would be any impact on diagnostics for non-recursive regexes, since closures and especially result builders can give less-than-useful error messages. I'm wondering if the use of a label somewhere could help, especially since it's not super clear at the use site what the role of the `wholeSentence` parameter is.

Good point. The recursive subpattern API could use some more exploration. I moved it to an alternative considered section in [apple/swift-evolution#1612](https://github.com/apple/swift-evolution/pull/1612).

> ****
>
> ## Future directions
> 
> ...
> 
> ### Recursive subpatterns
> 
> Sometimes, a textual regex may also use `(?R)` or `(?0)` to recusively evaluate the entire regex. For example, the following textual regex matches "I say you say I say you say hello".
> 
> ```swift
> (you|I) say (goodbye|hello|(?R))
> 
> ```
> 
> For this, `Regex` offers a special initializer that allows its pattern to recursively reference itself. This is somewhat akin to a fixed-point combinator.
> 
> ```swift
> extension Regex {
> public init<R: RegexComponent>(
> @RegexComponentBuilder _ content: (Regex<Substring>) -> R
> ) where R.Output == Match
> }
> 
> ```
> 
> With this initializer, the above regex can be expressed as the following using regex builder.
> 
> ```swift
> Regex { wholeSentence in
> ChoiceOf {
> "I"
> "you"
> }
> "say"
> ChoiceOf {
> "goodbye"
> "hello"
> wholeSentence
> }
> }
> 
> ```
> 
> There are some concerns with this design which we need to consider:
> 
> - Due to the lack of labeling, the argument to the builder closure can be arbitrarily named and cause confusion.
> - When there is an initializer that accepts a result builder closure, overloading that initializer with the same argument labels could lead to bad error messages upon interor type errors.

> [@Michael\_Ilseman](#):
>
> Just to double check, we're not precluding ourselves from supporting builder-time `if` in the future.

Builder-time conditions can still be supported with `buildOptional` and `buildEither` in the future. I think we need some future investigation to make sure it supports heterogeneous types in branches and won't conflict with regex conditionals.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [April 7, 2022, 1:50pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/15 "2022-04-07T13:50:14Z")

</div>

> [@rxwei](#):
>
> > [@Michael\_Ilseman](#):
> >
> > Just to double check, we're not precluding ourselves from supporting builder-time `if` in the future.
> 
> Builder-time conditions can still be supported with `buildOptional` and `buildEither` in the future. I think we need some future investigation to make sure it supports heterogeneous types in branches and won't conflict with regex conditionals.

Agreed. Richard and I discussed this in some detail, and concluded that not having support initially was the best option to leave the door open for implementing the most useful behavior in the future, rather than tying us to something that we'll regret later.

---

<div class="post-metadata">

**Author:** ![xAlien95](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xalien95/32/12558_2.png) [@xAlien95](https://forums.swift.org/u/xAlien95)\
**Post date:** [April 7, 2022, 10:29pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/16 "2022-04-07T22:29:31Z")

</div>

> [@Declarative String Processing Overview](https://forums.swift.org/t/declarative-string-processing-overview/52459/27):
>
> My dream is named captures via `let` bindings inside the result builder, allowing you to interact with them later in the builder as a kind of Swift take on backreferences. Something like monadic bind would allow you to accumulate and forward values (though I don't know enough about result builder design rationale to know whether this is sacrilege).

Since this is also my dream, I am afraid that allowing statements within the builder will preclude this eventuality. It's also unfortunate to have regular expression literals having labeled captures (which, in Swift, I guess will happen almost 100% of the times) to break code when converted into a combination of `Regex` DSLs and `Reference`s. Ideally, you shouldn't do anything after converting a regex literal into its DSL equivalent.

Also, is the current design capable of placing labeled regexes in `Regex` DSLs or are labeled tuples not handled by the 10-nple overloads?

* * *

Should the `transform` closure on `Try/Capture`s become a `.transform` method on instances of `RegexComponent`? It could be useful to be able to try a transformation without actually capturing the value.

* * *

Regarding the **Structured rather than flat captures** final section in the considered alternatives: I'm not sure it's a future-proof decision to split `Regex` and an hypothetical `Pattern` based on their capture structure and default semantics. If a more powerful, "Swifty" and structured `Pattern` is available, would users still use this hybrid `Regex` DSL?

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [April 7, 2022, 11:02pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/17 "2022-04-07T23:02:16Z")

</div>

> [@xAlien95](#):
>
> Also, is the current design capable of placing labeled regexes in `Regex` DSLs or are labeled tuples not handled by the 10-nple overloads?

Regex literals with named captures (labeled tuples) currently do not work as a builder component because builder methods on unlabeled tuples won't accept labeled tuples as arguments. To support this as a future direction I think we need a new type system feature.

In today's regex builder DSL you can use `Reference` instead to achieve similar functionality.

> **Example**
>
> ```swift
> let a = Reference(Substring.self)
> let b = Reference(Substring.self)
> let regex = Regex {
> Capture("abc", as: a)
> Capture("def", as: b)
> a
> Capture(b)
> }
> 
> if let result = input.firstMatch(of: regex) {
> print(result[a]) // => "abc"
> print(result[b]) // => "def"
> }
> 
> ```

> [@xAlien95](#):
>
> Should the `transform` closure on `Try/Capture` s become a `.transform` method on instances of `RegexComponent` ? It could be useful to be able to try a transformation without actually capturing the value.

This has been [discussed](https://forums.swift.org/t/pitch-regex-builder-dsl/56007/22) in the pitch thread. A method named `transform(_:)` or `map(_:)` on `RegexComponent` would be totally useful as a future direction, but it should have very different semantics from the `transform:` parameter on `Capture`/`TryCapture` initializer. A `map(_:)`, similar to other `map` methods, would transform the entire `Output` type.

The `transform:` parameter transforms _the most recent capture_, so if we were to make it a method, it would be called something like `mapFirstCapture(_:)` which I'm not sure reads as clearly as `Capture(..., transform: ...)`. Moreover, `mapFirstCapture(_:)` needs 10 overloads to support each capture arity.

---

<div class="post-metadata">

**Author:** ![valentinradu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/valentinradu/32/23005_2.png) [@valentinradu](https://forums.swift.org/u/valentinradu)\
**Post date:** [April 7, 2022, 11:45pm UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/18 "2022-04-07T23:45:36Z")

</div>

Probably an unpopular opinion and not really constructive to the proposal itself: much of the appeal of regex is in its concise form and reusability, oftentimes between different languages and platforms. With external tools able to decompose complex regex and help you create, test and understand it, I can't say I'd use a harder to read, less-concise, non-portable DSL (that I also have to learn first).  
Getting strong typed results from a regular regex (or fail) + compile time valid regex checks would be ideal (and enough in terms of safety) IMO.

---

<div class="post-metadata">

**Author:** ![scanon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/scanon/32/2445_2.png) [@scanon](https://forums.swift.org/u/scanon)\
**Post date:** [April 8, 2022, 12:12am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/19 "2022-04-08T00:12:26Z")

</div>

> [@valentinradu](#):
>
> Getting strong typed results from a regular regex (or fail) + compile time valid regex checks would be ideal (and enough in terms of safety) IMO.

That’s a very reasonable request, which is covered by a separate proposal (discussed some in SE-350, and more in a forthcoming proposal for the literal syntax).

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [April 8, 2022, 12:37am UTC](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531/20 "2022-04-08T00:37:46Z")

</div>

> [@xAlien95](#):
>
> Since this is also my dream, I am afraid that allowing statements within the builder will preclude this eventuality.

Could you elaborate? I don't see why this would preclude that at all. Also note that this is in the `RegexBuilder` module.

> [@xAlien95](#):
>
> Regarding the **Structured rather than flat captures** final section in the considered alternatives: I'm not sure it's a future-proof decision to split `Regex` and an hypothetical `Pattern` based on their capture structure and default semantics. If a more powerful, "Swifty" and structured `Pattern` is available, would users still use this hybrid `Regex` DSL?

Could you explain what you mean by future-proofing?

If `Pattern` existed powered by an improved Swift DSL / result builder story alongside better type operations, then clearly Regex would use that. Regex would be able to be used within a pattern and patterns could be regex components. This is all a little hand-wavy, because `Pattern` hasn't been fully designed and depends on language improvements.

As it is, this Regex DSL is helping to clarify and motivate those language improvements, such as variadic generics and issues around tuple labels.

[Next page](https://forums.swift.org/t/se-0351-regex-builder-dsl/56531.md?page=2)
