SE-0351: Regex Builder DSL

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
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"
}

This has been discussed 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.

1 Like