Skip to content

DSL quantifier types -> quantifier functions #126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 8, 2022

Conversation

rxwei
Copy link
Contributor

@rxwei rxwei commented Jan 25, 2022

Change quantifiers in the DSL from structure types to top-level functions. This allows for a lot more flexibility with overloading a quantifier based on the input Match type. The immediate benefit of this is getting rid of void and nested void types (see example below), and as a result eliminate the need for void-filtering within concatenation. A more important benefit (IMO) is being able to get rid of nominal tuples and switch back to Swift tuples, as Swift tuples enable strongly typed named captures and eliminates the complexity that comes with nominal tuples.

This PR is based on #114. Please review commit b14a85b.


Before:

let r0 = OneOrMore(.digit) // => `.Match == Tuple2<Substring, [()]>`
let r1 = Optionally(.digit) // => `.Match == Tuple2<Substring, ()?>`
let r2 = OneOrMore(Repeat(Optionally(.digit))) // => `.Match == Tuple2<Substring, [[()?]]>`
"123".match(r2) // => `RegexMatch<Tuple2<Substring, [[()?]]>>?`

After:

let r0 = oneOrMore(.digit) // => `.Match == Substring`
let r1 = optionally(.digit) // => `.Match == Substring`
let r2 = oneOrMore(many(optionally(.digit))) // => `.Match == Substring`
"123".match(r2) // => `RegexMatch<Substring>`

Before:

/(?<number>\d+)/ // => `Regex<Tuple2<Substring, Substring>>`

After:

/(?<number>\d+)/ // => `Regex<(Substring, number: Substring)>`

@rxwei rxwei force-pushed the quantifier-functions branch from 76b6fb6 to b14a85b Compare January 31, 2022 04:08
@rxwei rxwei requested a review from milseman January 31, 2022 04:12
@rxwei rxwei force-pushed the quantifier-functions branch 2 times, most recently from d279040 to f8d5918 Compare February 7, 2022 08:38
@rxwei
Copy link
Contributor Author

rxwei commented Feb 7, 2022

@swift-ci please test Linux

if arity == 0 {
return genericParameters()
}
return "Tuple\(arity)<\(genericParameters())>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the PR that drops the nominal public types, or a different one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, are we dropping them for literal but not result builder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The public types, e.g. Concatenation_0_1, will be dropped in a follow-up PR.

…ions. This allows for a lot more flexibility with overloading a quantifier based on the input `Match` type. The immediate benefit of this is getting rid of void and nested void types (see example below), and as a result eliminate the need for void-filtering within concatenation. A more important benefit is being able to get rid of nominal tuples and switch back to Swift tuples, as Swift tuples enable strongly typed named captures and eliminates the complexity that comes with nominal tuples.

-----

Before:
```swift
let r0 = OneOrMore(.digit) // => `.Match == Tuple2<Substring, [()]>`
let r1 = Optionally(.digit) // => `.Match == Tuple2<Substring, ()?>`
let r2 = OneOrMore(Repeat(Optionally(.digit))) // => `.Match == Tuple2<Substring, [[()?]]>`
"123".match(r2) // => `RegexMatch<Tuple2<Substring, [[()?]]>>?`
```
After:
```swift
let r0 = oneOrMore(.digit) // => `.Match == Substring`
let r1 = optionally(.digit) // => `.Match == Substring`
let r2 = oneOrMore(many(optionally(.digit))) // => `.Match == Substring`
"123".match(r2) // => `RegexMatch<Substring>`
```

-----

Before:
```swift
/(?<number>\d+)/ // => `Regex<Tuple2<Substring, Substring>>`
```

After:
```swift
/(?<number>\d+)/ // => `Regex<(Substring, number: Substring)>`
```
@rxwei rxwei force-pushed the quantifier-functions branch from f8d5918 to 7996289 Compare February 8, 2022 00:11
@milseman
Copy link
Member

milseman commented Feb 8, 2022

@swift-ci please test linux platform

Copy link
Member

@milseman milseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rxwei
Copy link
Contributor Author

rxwei commented Feb 8, 2022

@swift-ci please test Linux

@rxwei rxwei merged commit 6045698 into swiftlang:main Feb 8, 2022
@rxwei rxwei deleted the quantifier-functions branch February 8, 2022 01:28
rxwei added a commit to rxwei/swift-experimental-string-processing that referenced this pull request Mar 10, 2022
Replace free functions such as `oneOrMore` with types such as `OneOrMore`. This hides overloads of free functions as initializers within those types. It also makes the DSL consistent with SwiftUI.

- `oneOrMore` -> `OneOrMore`
- `zeroOrMore` -> `ZeroOrMore`
- `optionally` -> `Optionally`
- `repeating` -> `Repeat`
- `choiceOf` -> `ChoiceOf`
- `capture` -> `Capture`
- `tryCapture` -> `TryCapture`

Note: The reason we didn't realize this was possible (e.g. in swiftlang#126) was because we were narrowly focused on including the subpattern type in the quantifier/combinator's generic parameter, i.e. `OneOrMore<Component: RegexComponent>`, which made it impossible to deduce each type's `typealias Match` from `Component`. Now we have an unconstrained generic parameter (e.g. `OneOrMore<Match>`) which gives us the full flexibility to hide `Match` deduction rules in initializers' type signatures.
rxwei added a commit to rxwei/swift-experimental-string-processing that referenced this pull request Mar 11, 2022
Replace free functions such as `oneOrMore` with types such as `OneOrMore`. This hides overloads of free functions as initializers within those types. It also makes the DSL consistent with SwiftUI.

- `oneOrMore` -> `OneOrMore`
- `zeroOrMore` -> `ZeroOrMore`
- `optionally` -> `Optionally`
- `repeating` -> `Repeat`
- `choiceOf` -> `ChoiceOf`
- `capture` -> `Capture`
- `tryCapture` -> `TryCapture`

Note: The reason we didn't realize this was possible (e.g. in swiftlang#126) was because we were narrowly focused on including the subpattern type in the quantifier/combinator's generic parameter, i.e. `OneOrMore<Component: RegexComponent>`, which made it impossible to deduce each type's `typealias Match` from `Component`. Now we have an unconstrained generic parameter (e.g. `OneOrMore<Match>`) which gives us the full flexibility to hide `Match` deduction rules in initializers' type signatures.
rxwei added a commit to rxwei/swift-experimental-string-processing that referenced this pull request Mar 11, 2022
Replace free functions such as `oneOrMore` with types such as `OneOrMore`. This hides overloads of free functions as initializers within those types. It also makes the DSL consistent with SwiftUI.

- `oneOrMore` -> `OneOrMore`
- `zeroOrMore` -> `ZeroOrMore`
- `optionally` -> `Optionally`
- `repeating` -> `Repeat`
- `choiceOf` -> `ChoiceOf`
- `capture` -> `Capture`
- `tryCapture` -> `TryCapture`

Note: The reason we didn't realize this was possible (e.g. in swiftlang#126) was because we were narrowly focused on including the subpattern type in the quantifier/combinator's generic parameter, i.e. `OneOrMore<Component: RegexComponent>`, which made it impossible to deduce each type's `typealias Match` from `Component`. Now we have an unconstrained generic parameter (e.g. `OneOrMore<Match>`) which gives us the full flexibility to hide `Match` deduction rules in initializers' type signatures.
rxwei added a commit to rxwei/swift-experimental-string-processing that referenced this pull request Mar 18, 2022
Replace free functions such as `oneOrMore` with types such as `OneOrMore`. This hides overloads of free functions as initializers within those types. It also makes the DSL consistent with SwiftUI.

- `oneOrMore` -> `OneOrMore`
- `zeroOrMore` -> `ZeroOrMore`
- `optionally` -> `Optionally`
- `repeating` -> `Repeat`
- `choiceOf` -> `ChoiceOf`
- `capture` -> `Capture`
- `tryCapture` -> `TryCapture`

Note: The reason we didn't realize this was possible (e.g. in swiftlang#126) was because we were narrowly focused on including the subpattern type in the quantifier/combinator's generic parameter, i.e. `OneOrMore<Component: RegexComponent>`, which made it impossible to deduce each type's `typealias Match` from `Component`. Now we have an unconstrained generic parameter (e.g. `OneOrMore<Match>`) which gives us the full flexibility to hide `Match` deduction rules in initializers' type signatures.
rxwei added a commit to rxwei/swift-experimental-string-processing that referenced this pull request Mar 21, 2022
Replace free functions such as `oneOrMore` with types such as `OneOrMore`. This hides overloads of free functions as initializers within those types. It also makes the DSL consistent with SwiftUI.

- `oneOrMore` -> `OneOrMore`
- `zeroOrMore` -> `ZeroOrMore`
- `optionally` -> `Optionally`
- `repeating` -> `Repeat`
- `choiceOf` -> `ChoiceOf`
- `capture` -> `Capture`
- `tryCapture` -> `TryCapture`

Note: The reason we didn't realize this was possible (e.g. in swiftlang#126) was because we were narrowly focused on including the subpattern type in the quantifier/combinator's generic parameter, i.e. `OneOrMore<Component: RegexComponent>`, which made it impossible to deduce each type's `typealias Match` from `Component`. Now we have an unconstrained generic parameter (e.g. `OneOrMore<Match>`) which gives us the full flexibility to hide `Match` deduction rules in initializers' type signatures.
rxwei added a commit to rxwei/swift-experimental-string-processing that referenced this pull request Mar 21, 2022
Replace free functions such as `oneOrMore` with types such as `OneOrMore`. This hides overloads of free functions as initializers within those types. It also makes the DSL consistent with SwiftUI.

- `oneOrMore` -> `OneOrMore`
- `zeroOrMore` -> `ZeroOrMore`
- `optionally` -> `Optionally`
- `repeating` -> `Repeat`
- `choiceOf` -> `ChoiceOf`
- `capture` -> `Capture`
- `tryCapture` -> `TryCapture`

Note: The reason we didn't realize this was possible (e.g. in swiftlang#126) was because we were narrowly focused on including the subpattern type in the quantifier/combinator's generic parameter, i.e. `OneOrMore<Component: RegexComponent>`, which made it impossible to deduce each type's `typealias Match` from `Component`. Now we have an unconstrained generic parameter (e.g. `OneOrMore<Match>`) which gives us the full flexibility to hide `Match` deduction rules in initializers' type signatures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants