Further updates to dataspacePatterns

This commit is contained in:
Tony Garnock-Jones 2024-04-09 11:07:03 +02:00
parent 56d9d3e89d
commit e4d0be69ba
1 changed files with 44 additions and 47 deletions

View File

@ -19,7 +19,14 @@ corresponds to a (possibly-nested) [binding pattern](#binding) in the overall pa
Consider the pattern: Consider the pattern:
```preserves ```preserves
<arr {0:<lit 1> 1:<bind <arr {0:<bind <_>> 1:<_>}>> 2:<_>}> <group <arr> {
0: <lit 1>
1: <bind <group <arr> {
0: <bind <_>>
1: <_>
}>>
2: <_>
}>
``` ```
Each of the following values yields different results when matched against it: Each of the following values yields different results when matched against it:
@ -39,41 +46,36 @@ Each of the following values yields different results when matched against it:
## Abstract syntax of patterns ## Abstract syntax of patterns
A *pattern* may be either a *discard*, a (nested) *binding*, a *literal*, or a *compound*. A *pattern* may be either a *discard*, a (nested) *binding*, a *literal*, or a *group* (compound).
```preserves-schema ```preserves-schema
Pattern = DDiscard / DBind / DLit / DCompound . Pattern =
/ @discard <_>
/ <bind @pattern Pattern>
/ <lit @value AnyAtom>
/ <group @type GroupType @entries { any: Pattern ...:... }>
.
``` ```
### Discard ### Discard
A *discard pattern* matches any input value. A *discard pattern*, `<_>`, matches any input value.
```preserves-schema
DDiscard = <_>.
```
### Binding ### Binding
A *binding pattern* speculatively pushes the portion of the input under consideration onto the A *binding pattern*, `<bind ...>`, speculatively pushes the portion of the input under
end of the binding sequence being built, and then recursively evaluates its subpattern. If the consideration onto the end of the binding sequence being built, and then recursively evaluates
subpattern succeeds, so does the overall binding pattern (keeping the binding); otherwise, the its subpattern. If the subpattern succeeds, so does the overall binding pattern (keeping the
speculative addition to the binding sequence is undone, and the overall binding pattern fails. binding); otherwise, the speculative addition to the binding sequence is undone, and the
overall binding pattern fails.
```preserves-schema
DBind = <bind @pattern Pattern>.
```
### Literal ### Literal
A *literal pattern* matches any **atomic** Preserves value. In order to match a literal A *literal pattern*, `<lit ...>`, matches any **atomic** Preserves value:
**compound** value, a combination of compound and literal patterns must be used.
```preserves-schema ```preserves-schema
DLit = <lit @value AnyAtom>.
AnyAtom = AnyAtom =
/ @bool bool / @bool bool
/ @float float
/ @double double / @double double
/ @int int / @int int
/ @string string / @string string
@ -83,39 +85,34 @@ AnyAtom =
. .
``` ```
### Compound In order to match a literal **compound** value, a combination of group and literal patterns
must be used.
Each *compound pattern* first checks the type of its input: a `rec` pattern fails unless it is ### Group
given a Record, an `arr` demands a Sequence and a `dict` only matches a Dictionary.
Each *group pattern* first checks the type of its input: a `rec` pattern fails unless it is
given a Record having the specified `label`, an `arr` demands a Sequence and a `dict` only
matches a Dictionary.
```preserves-schema ```preserves-schema
DCompound = <rec @label any @fields { int: Pattern ...:... }> GroupType =
/ <arr @items { int: Pattern ...:... }> / <rec @label any>
/ <dict @entries { any: Pattern ...:... }> . / <arr>
/ <dict>
.
``` ```
If the type check fails, the pattern match fails. Otherwise, matching continues: If the type check fails, the pattern match fails. Otherwise, matching continues. Subpatterns in
the `entries` field in the group pattern are considered in increasing Preserves order of
key.[^dict-pattern-ordering] For Records, each key must be a field index; for Sequences, each
key is an element index; and for Dictionaries, keys are just keys in the dictionary to be
matched. Each subpattern is matched against the corresponding portion of the input, failing if
no such item exists.
- `rec` patterns compare the label of the input Record against the `label` field in the Group patterns ignore keys in values being matched that are not mentioned in the pattern.
pattern; unless they match literally and exactly, the overall match fails. Otherwise, Matching succeeds if such values have *more* than the structure and information required of
subpatterns in `fields` are considered in increasing order of key. Each key in `fields` is them by a given pattern, but not if they have less. This allows for protocol extension: for
the index of an input record field to examine. Each subpattern is matched against the example, records with "extra" fields will continue to match.
corresponding field in the input, failing if no such field exists. The overall pattern thus
ignores any position in the input record for which no subpattern exists.
- `arr` patterns are similar, except without the need for a label check. Subpatterns in
`items` are processed in order of key. Each key is interpreted as an element index. Excess
or unexamined input elements are ignored.
- `dict` patterns consider each of the key/subpattern pairs in `entries` in turn, according to
the Preserves order of the keys.[^dict-pattern-ordering] If any given key from the pattern
is not present in the input value, matching fails. Otherwise, matching proceeds recursively.
The pattern ignores keys in the input value that are not mentioned in the pattern.
These rules treat Record, Sequence and Dictionary values similarly: matching will succeed if
such values have *more* than the structure and information required of them by a given pattern,
but not if they have less. This allows for protocol extension: for example, records with
"extra" fields will continue to match.
--- ---