Preserves schemas

This commit is contained in:
Tony Garnock-Jones 2022-06-01 14:47:24 +02:00
parent 7433ef3f94
commit 268c652f6b
4 changed files with 123 additions and 3 deletions

View File

@ -46,9 +46,9 @@
# Protocols and Schema Definitions
- [Preserves schemas]()
- [Preserves Schema metaschema]()
- [Preserves Path schema]()
- [Preserves schemas](protocols/preserves/index.md)
- [Preserves Schema metaschema](protocols/preserves/schema.md)
- [Preserves Path schema](protocols/preserves/path.md)
- [Syndicated Actor Model schemas]()
- ["Observe" assertions]()
- [Patterns over assertions]()

View File

@ -0,0 +1,4 @@
# Preserves schemas
The following pages document schemas associated with the [Preserves](../../guide/preserves.md)
data language and its tools.

View File

@ -0,0 +1,108 @@
# Preserves Path schema
[Preserves Path](https://preserves.dev/preserves-path.html) is a language for selecting and
filtering portions of a Preserves value. It has an associated schema describing the various
kinds of Path expressions as abstract syntax.
The schema source below is taken from
[path/path.prs](https://gitlab.com/preserves/preserves/-/blob/main/path/path.prs) in the
[Preserves source code repository](https://gitlab.com/preserves/preserves).
Preserves Path expressions come in several flavours: selectors, steps (axes and filters), and
predicates. Each is described below along with its abstract syntax definitions.
## Selectors and Steps
*Selectors* are a sequence of *steps*, applied one after the other to the currently-selected
value. Each step transforms an input into zero or more outputs. A step is an *axis* or a
*filter*.
```preserves-schema
Selector = [Step ...] .
Step = Axis / Filter .
```
## Axes: selecting portions of the input
Each *axis* step generally selects some sub-portion or -portions of the current document. An
axis may also have a secondary filtering effect: for example, `label` only applies to Records,
and will yield an empty result set when applied to any other kind of input.
```preserves-schema
Axis =
/ <values> ;; yields the immediate subvalues of the input nonrecursively
/ <descendants> ;; recurses through all descendant subvalues of the input
/ <at @key any> ;; extracts a subvalue named by the given key, if any
/ <label> ;; extracts a Record's label, if any
/ <keys> ;; extracts all keys (for subvalues) of the input, nonrecursively
/ <length> ;; extracts the length/size of the input, if any
/ <annotations> ;; extracts all annotations attached to the input
/ <embedded> ;; moves into the representation of an embedded value, if any
/ <parse @module [symbol ...] @name symbol> ;; parses using Preserves Schema
/ <unparse @module [symbol ...] @name symbol> ;; unparses using Preserves Schema
.
```
The `parse` and `unparse` variants name [Schema](../../guide/preserves.md#schemas) definitions,
to be resolved by the eventual surrounding context in which the expression will be executed. A
`parse` axis parses the input using a Schema definition; if the parse succeeds, the axis moves
into the parse result. Similarly, `unparse` expects an abstract parse result, transforming it
back into a concrete value according to the Schema definition.
## Filters: rejecting inputs
Each *filter* step generally applies some test to the current document as a whole, either
emitting it unchanged (with exceptions, detailed below) or emitting no outputs at all.
```preserves-schema
Filter =
/ <nop> ;; Always emit the input
/ <compare @op Comparison @literal any> ;; Emit iff the comparison holds
/ <regex @regex string> ;; Emit iff input is String and regex matches
/ <test @pred Predicate> ;; Apply complex predicate
/ <real> ;; Emit iff input is Float, Double, or Integer
/ <int> ;; TRUNCATE and emit iff Float, Double or Integer
/ <kind @kind ValueKind> ;; Emit iff input kind matches
.
```
### Complex predicates
The complex predicates in a `test` filter are built up from logical connectives over selectors.
A `Selector` predicate evaluates to true whenever, applied to its input, it results in a
non-empty output set.
```preserves-schema
Predicate =
/ Selector
/ <not @pred Predicate>
/ <or @preds [Predicate ...]>
/ <and @preds [Predicate ...]>
.
```
### Comparison against a literal
Each `compare` filter includes a `Comparison` and a literal value to compare the input against.
For example, `<compare eq 3>` only produces an output if the input is equal (according to the
[Preserves semantic model](https://preserves.dev/preserves.html#starting-with-semantics)) to
`3`.
```preserves-schema
Comparison = =eq / =ne / =lt / =ge / =gt / =le .
```
**NB.** For inequalities (`lt`/`ge`/`gt`/`le`), comparison between values of different kinds is
undefined in the current draft specification.
### Filtering by value kind
Each `kind` filter selects only values from one of the kinds of Preserves value:
```preserves-schema
ValueKind =
/ =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol
/ =Record / =Sequence / =Set / =Dictionary
/ =Embedded
.
```

View File

@ -0,0 +1,8 @@
# Preserves Schema metaschema
The Preserves Schema metaschema defines the structure of the abstract syntax (AST) of schemas.
Every valid Preserves Schema document can be represented as an instance of the metaschema. (And
of course the metaschema is itself a schema, which is in turn an instance of the metaschema!)
⟶ See [Appendix A: "Metaschema" of the Preserves Schema
specification](https://preserves.dev/preserves-schema.html#appendix-metaschema).