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:
```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:
@ -39,41 +46,36 @@ Each of the following values yields different results when matched against it:
## 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
Pattern = DDiscard / DBind / DLit / DCompound .
Pattern =
/ @discard <_>
/ <bind @pattern Pattern>
/ <lit @value AnyAtom>
/ <group @type GroupType @entries { any: Pattern ...:... }>
.
```
### Discard
A *discard pattern* matches any input value.
```preserves-schema
DDiscard = <_>.
```
A *discard pattern*, `<_>`, matches any input value.
### Binding
A *binding pattern* speculatively pushes the portion of the input under consideration onto the
end of the binding sequence being built, and then recursively evaluates its subpattern. If the
subpattern succeeds, so does the overall binding pattern (keeping the binding); otherwise, the
speculative addition to the binding sequence is undone, and the overall binding pattern fails.
```preserves-schema
DBind = <bind @pattern Pattern>.
```
A *binding pattern*, `<bind ...>`, speculatively pushes the portion of the input under
consideration onto the end of the binding sequence being built, and then recursively evaluates
its subpattern. If the subpattern succeeds, so does the overall binding pattern (keeping the
binding); otherwise, the speculative addition to the binding sequence is undone, and the
overall binding pattern fails.
### Literal
A *literal pattern* matches any **atomic** Preserves value. In order to match a literal
**compound** value, a combination of compound and literal patterns must be used.
A *literal pattern*, `<lit ...>`, matches any **atomic** Preserves value:
```preserves-schema
DLit = <lit @value AnyAtom>.
AnyAtom =
/ @bool bool
/ @float float
/ @double double
/ @int int
/ @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
given a Record, an `arr` demands a Sequence and a `dict` only matches a Dictionary.
### Group
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
DCompound = <rec @label any @fields { int: Pattern ...:... }>
/ <arr @items { int: Pattern ...:... }>
/ <dict @entries { any: Pattern ...:... }> .
GroupType =
/ <rec @label any>
/ <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
pattern; unless they match literally and exactly, the overall match fails. Otherwise,
subpatterns in `fields` are considered in increasing order of key. Each key in `fields` is
the index of an input record field to examine. Each subpattern is matched against the
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.
Group patterns ignore keys in values being matched that are not mentioned in the pattern.
Matching succeeds 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.
---