Use records instead of dictionaries

This commit is contained in:
Tony Garnock-Jones 2023-11-01 11:57:23 +01:00
parent ae7555f6f3
commit 9ae16b4561
1 changed files with 34 additions and 42 deletions

View File

@ -3,7 +3,7 @@ title: "P-expressions"
--- ---
Tony Garnock-Jones <tonyg@leastfixedpoint.com> Tony Garnock-Jones <tonyg@leastfixedpoint.com>
October 2023. Version 0.1.2. October 2023. Version 0.2.0.
This document defines a grammar called *Preserves Expressions* This document defines a grammar called *Preserves Expressions*
(*P-expressions*, *pexprs*) that includes [ordinary Preserves text (*P-expressions*, *pexprs*) that includes [ordinary Preserves text
@ -105,35 +105,27 @@ We write ⌜*p*⌝ for the encoding into Preserves of P-expression *p*.
| ⌜·⌝ : **P-expression** | ⟶ | **Preserves** | | ⌜·⌝ : **P-expression** | ⟶ | **Preserves** |
Aside from `Group`, `Block`, `Comma`, `Semicolon`, `Colons`, `Trailer`, Aside from `Group`, `Block`, `Comma`, `Semicolon`, `Colons`, `Trailer`,
and empty `Record`, P-expressions are encoded directly as Preserves and `Record`, P-expressions are encoded directly as Preserves data.
data.
{:.pseudocode.equations} {:.pseudocode.equations}
| ⌜`[`*p* ...`]`⌝ | = | `[`⌜*p*⌝ ...`]` | | ⌜`[`*p* ...`]`⌝ | = | `[`⌜*p*⌝ ...`]` |
| ⌜`<`*p* ...`>`⌝ | = | `<`⌜*p*⌝ ...`>` |
| ⌜`#{`*p* ...`}`⌝ | = | `#{`⌜*p*⌝ ...`}` | | ⌜`#{`*p* ...`}`⌝ | = | `#{`⌜*p*⌝ ...`}` |
| ⌜`#!`*p*⌝ | = | `#!`⌜*p*⌝ | | ⌜`#!`*p*⌝ | = | `#!`⌜*p*⌝ |
| ⌜`@`*p* *q*⌝ | = | `@`⌜*p*⌝ ⌜*q*⌝ | | ⌜`@`*p* *q*⌝ | = | `@`⌜*p*⌝ ⌜*q*⌝ |
| ⌜*p*⌝ | = | *p* when *p***Atom** | | ⌜*p*⌝ | = | *p* when *p***Atom** |
Everything else is encoded as Preserves Everything else is encoded as Preserves records.
dictionaries.[^encoding-rationale]
[^encoding-rationale]: In principle, it would be nice to use *records*
for this purpose, but if we did so we would have to also encode
usages of records!
{:.pseudocode.equations} {:.pseudocode.equations}
| ⌜`<>`⌝ | = | `{r:[]}` | | ⌜`<`*p* ...`>`⌝ | = | `<r` ⌜*p*⌝ ...`>` |
| ⌜`(`*p* ...`)`⌝ | = | `{g:[`⌜*p*⌝ ...`]}` | | ⌜`(`*p* ...`)`⌝ | = | `<g` ⌜*p*⌝ ...`>` |
| ⌜`{`*p* ...`}`⌝ | = | `{b:[`⌜*p*⌝ ...`]}` | | ⌜`{`*p* ...`}`⌝ | = | `<b` ⌜*p*⌝ ...`>` |
| ⌜`,`⌝ | = | `{s:|,|}` | | ⌜`,`⌝ | = | `<s |,|>` |
| ⌜`;`⌝ | = | `{s:|;|}` | | ⌜`;`⌝ | = | `<s |;|>` |
| ⌜`:` ...⌝ | = | `{s:|:` ...`|}` | | ⌜`:` ...⌝ | = | `<s |:` ...`|>` |
| ⌜*t*⌝ | = | ⌜*a*⌝ ... `{}`, where *a* ... are the annotations in *t* and *t***Trailer** | | ⌜*t*⌝ | = | ⌜*a*⌝ ... `<a>`, where *a* ... are the annotations in *t* and *t***Trailer** |
The empty dictionary `{}` acts as an anchor for the annotations in a The record `<a>` acts as an anchor for the annotations in a `Trailer`.
`Trailer`.
We overload the ⌜·⌝ notation for encoding whole `Document`s into We overload the ⌜·⌝ notation for encoding whole `Document`s into
sequences of Preserves values. sequences of Preserves values.
@ -179,25 +171,25 @@ text-syntax encodings.
```preserves ```preserves
<date 1821 (lookup-month "February") 3> <date 1821 (lookup-month "February") 3>
= <date 1821 {g:[lookup-month "February"]} 3> = <r date 1821 <g lookup-month "February"> 3>
``` ```
```preserves ```preserves
<>⌝ <>⌝
= {r:[]} = <r>
``` ```
```preserves ```preserves
⌜(begin (println! (+ 1 2)) (+ 3 4))⌝ ⌜(begin (println! (+ 1 2)) (+ 3 4))⌝
= {g:[begin {g:[println! {g:[+ 1 2]}]} {g:[+ 3 4]}]} = <g begin <g println! <g + 1 2>> <g + 3 4>>
``` ```
```preserves ```preserves
⌜()⌝ ⌜()⌝
= {g:[]} = <g>
⌜[() () ()]⌝ ⌜[() () ()]⌝
= [{g:[]}, {g:[]}, {g:[]}] = [<g>, <g>, <g>]
``` ```
```preserves ```preserves
@ -209,20 +201,20 @@ text-syntax encodings.
} }
tearDown(); tearDown();
}⌝ }⌝
= {b:[ = <b
setUp {g:[]} {s:|;|} setUp <g> <s |;|>
# Now enter the loop # Now enter the loop
loop {s:|:|} {b:[ loop <s |:|> <b
greet {g:["World"]} {s:|;|} greet <g "World"> <s |;|>
]} >
tearDown {g:[]} {s:|;|} tearDown <g> <s |;|>
]} >
``` ```
```preserves ```preserves
⌜[1 + 2.0, print "Hello", predicate: #t, foo, #!remote, bar]⌝ ⌜[1 + 2.0, print "Hello", predicate: #t, foo, #!remote, bar]⌝
= [1 + 2.0 {s:|,|} print "Hello" {s:|,|} predicate {s:|:|} #t {s:|,|} = [1 + 2.0 <s |,|> print "Hello" <s |,|> predicate <s |:|> #t <s |,|>
foo {s:|,|} #!remote {s:|,|} bar] foo <s |,|> #!remote <s |,|> bar]
``` ```
```preserves ```preserves
@ -230,10 +222,10 @@ text-syntax encodings.
optional name: string, optional name: string,
address: Address, address: Address,
}⌝ }⌝
= {b:[ = <b
optional name {s:|:|} string {s:|,|} optional name <s |:|> string <s |,|>
address {s:|:|} Address {s:|,|} address <s |:|> Address <s |,|>
]} >
``` ```
### Whole `Document`s ### Whole `Document`s
@ -244,12 +236,12 @@ text-syntax encodings.
# example of a comment at the end of a dictionary # example of a comment at the end of a dictionary
} }
# example of a comment at the end of the input file⌝ # example of a comment at the end of the input file⌝
= [ {b:[ = [ <b
key {s:|:|} value key <s |:|> value
@"example of a comment at the end of a dictionary" {} @"example of a comment at the end of a dictionary" <a>
]} >
@"example of a comment at the end of the input file" @"example of a comment at the end of the input file"
{} <a>
] ]
``` ```