# Declarative String Processing Overview

**URL:** <https://forums.swift.org/t/declarative-string-processing-overview/52459>\
**Category:** Pitches\
**Created:** [September 29, 2021, 11:13pm UTC](https://forums.swift.org/t/declarative-string-processing-overview/52459 "2021-09-29T23:13:12Z")\
**Posts on this page:** 1\
**Showing post:** 27

<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:** [September 30, 2021, 3:53pm UTC](https://forums.swift.org/t/declarative-string-processing-overview/52459/27 "2021-09-30T15:53:36Z")

</div>

> [@Chris\_Eidhof](#):
>
> One thing I would improve is being able to bind variable names where you declare them. In your `graphemeBreakPropertyData` , it'd be cool if we can somehow declare the variable names inside the result builder, rather than using `captures` . I realise this is not a trivial change and something that needs a lot more thinking / designing.

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).

> [@Patrick\_Gili](#):
>
> how can you determine how many characters were consumed?

The direct way would be by calling `Collection.distance()` with the returned indices. We could expose a method on the match result to calculate that for you.

We're unlikely to eagerly track the count during matching, as we'd rather operate directly over the UTF-8 bytes whenever possible without having to run grapheme-breaking for everything.

> [@siracusa](#):
>
> Setting aside `Pattern` s and [Raku Grammars](https://docs.raku.org/language/grammars) for now

I definitely do want to talk about them! But that's a much longer reply that I'm drafting.

> [@siracusa](#):
>
> Something like this looks much nicer:
> 
> ```swift
> let (l, u, p) = line.match(/([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s*;\s(\w+).*/)
> 
> ```

As outlined, the result of a match would be some kind of match object containing information about the overall match alongside captures, so you'd have to stick a `.captures` on the end.

That being said, I'm a big fan of allowing types to define custom tuple destructuring, so it's possible that statement would work as-is. It does open the door to ad-hoc type relationships when you can't just parameterize over a generic, but no more so than [destructing matching](https://gist.github.com/milseman/bb39ef7f170641ae52c13600a512782f#pattern-matching-through-conformance-to-pattern) or even [collection algorithms](https://github.com/milseman/swift-evolution/blob/collections_om_nom_nom/Sources/Prototype_CollectionConsumerSearcher/CharactetSet.swift).

I expect there to be a lot of pressure on the final design to eliminate such boilerplate, so it's good to be talking about, and identifying, ad hoc type relationships now.

> [@kylemacomber](#):
>
> Alternatively, extracting matches and captures could be defined as two different algorithms.

Right, API design might obviate concerns about the return type.

---

_[View the full topic](https://forums.swift.org/t/declarative-string-processing-overview/52459)._
