Update TODO.md

This commit is contained in:
Tony Garnock-Jones 2019-08-18 23:06:28 +01:00
parent 389b74bf87
commit f4beba8b7a
1 changed files with 82 additions and 85 deletions

167
TODO.md
View File

@ -30,32 +30,29 @@ naming a subterm within a Preserve. Record labels would be a kind of
assertion on the current node. Indexes and keys would be steps. It'd
be a lot like xpath I think; see also my `racket-xe` package.
- `child()` - moves into direct children
- `descendant-or-self()` - moves into direct and indirect children, including this node
- `descendant()` - moves into direct and indirect children, excluding this node
- `where[P*]` - "where" clause, applies nested path, keeping nodes with submatches
- `or[P*]` - result of first non-empty `P` match
- `at(K)` - moves into direct children whose keys are `K` from
- `<child>` - moves into direct children
- `<descendant-or-self>` - moves into direct and indirect children, including this node
- `<descendant>` - moves into direct and indirect children, excluding this node
- `<where[P*]>` - "where" clause, applies nested path, keeping nodes with submatches
- `<or[P*]>` - result of first non-empty `P` match
- `<at K>` - moves into direct children whose keys are `K` from
dictionaries, sequences or records; `K` should be a number for the
latter two
- `label()` - moves into labels of records
- `equals(V)` - filters to only nodes that equal `V`
- `isa(T)` - filters to only nodes that are `T ∈
[boolean float double signed-integer string byte-string symbol record sequence set dictionary]`
- `<label>` - moves into labels of records
- `<equals V>` - filters to only nodes that equal `V`
- `<isa T>` - filters to only nodes that are `T ∈
{boolean float double signed-integer string byte-string symbol record sequence set dictionary}`
Abbreviations:
/ = child()
// = descendant-or-self()
[P*] = where[P*]
Symbol = [label() equals(Symbol)]
NonSymbolAtom = at(NonSymbolAtom)
/ = <child>
// = <descendant-or-self>
[P*] = <where[P*]>
Symbol = [<label> <equals Symbol>]
NonSymbolAtom = <at NonSymbolAtom>
# TODO
- [DONE] allow `label[1,2,3]` and `label{a:b, c:d}`, meaning
`label([1,2,3])` and `label({a:b, c:d})`.
- explain why total order / comparison of values is important and/or useful
- what does having a total order unlock?
- explain why records are good (see below on yaml tags etc)
@ -184,38 +181,38 @@ Abbreviations:
- So then for us, where we have kind of union types more than
labelled sums:
- `equals(value)`, `lessthan(value)`, `greaterthan(value)`
- `<equals Value>`, `<lessthan Value>`, `<greaterthan Value>`
- must be equal to / less than / greater than this value
- maybe take `range(lo,hi)` as primitive?
- maybe take `<range lo hi>` as primitive?
- no, because of infinitesimals
- `regexp(string)` ... etc? (Perhaps `pattern(regexpstring)`
- `<regexp string>` ... etc? (Perhaps `<pattern regexpstring>`
is better) (Be sure to specify ECMA-262 dialect, with
restrictions a la JSON-schema
https://json-schema.org/latest/json-schema-validation.html#rfc.section.4.3)
- identifier naming a type definition
- some type definitions are builtin: `Boolean = union(equals(true), equals(false))`
- some type definitions are builtin: `Boolean = <union <equals #true> <equals #false>>`
- some have to be primitive rather than builtin, like
`SignedInteger` or `Double`, because they have unboundedly
(or awkwardly) many inhabitants and the class above or
below them doesn't have a limit ordinal in the right place
- parameters/`forall`?
- `record(type, type, ...)` - first one is the label type
- `list(type, ...)` - heterogeneous list of specific types
- `listof(type)` - homogeneous list
- `setof(type)`
- `{ keytype: valuetype, ... }` - heterogeneous dict
- wait, `{ keyliteral: valuetype, ... }` might be better - sugar for
`dict([equals(keyliteral), valuetype], ...)`
- `dict*(...)` for when extra members are allowed
- `<record Type Type ...>` - first one is the label type
- `<list Type ...>` - heterogeneous list of specific types
- `<listof Type>` - homogeneous list
- `<setof Type>`
- `{ keyType: valueType, ... }` - heterogeneous dict
- wait, `{ keyLiteral: valueType, ... }` might be better - sugar for
`<dict [<equals keyLiteral> valueType] ...>`
- `<dict+ ...>` for when extra members are allowed
- what about optional members?
- `dictof(keytype, valuetype)` - homogeneous dict
- `union(type, ...)`
- `<dictof keyType valueType>` - homogeneous dict
- `<union Type ...>`
- empty union is uninhabited type(!)
- a kind of or
- `and(type, ...)`
- `<and Type ...>`
- simultaneous constraints on type, for range, or for range-and-type
- a kind of intersection; parallel reduction
- `interleave(type, ...)` ?? maybe, if sequences are a thing?
- `<interleave Type ...>` ?? maybe, if sequences are a thing?
Could be good for organizing key-value mappings in
dictionary-brackets, because unordered... and sets...
@ -229,40 +226,40 @@ Abbreviations:
a1.a & b1.b = a1.(a & b1.b) + b1.(a1.a & b)
- Take two.
- `=(value)`, `<(value)`, `>(value)`, `<=`, `>=`, *eq *lt *gt *le *ge
- `_` for discard, `*discard()`
- scalar values not symbols beginning with `*` match themselves as if they were `=`-wrapped
- `<== Value >`, `<|<| value>`, `<|>| value>`, `|<=|`, `|>=|`, `*eq` `*lt` `*gt` `*le` `*ge`
- `_` for discard, `<*discard>`
- scalar values not symbols beginning with `*` match themselves as if they were `==`-wrapped
- all the special things are records, possibly 0-ary, with labels symbols starting with `*`
except for `=` etc and `_` and `...`
- if you have to match a label like `*foo` it might clash, so match `=(*foo)` instead:
`*foo(1 2 3)` ==> `=(*foo)(1 2 3)`
- `*int()` for `SignedInteger`, `*string()`, `*symbol()`,
`*bytestring()`/`*binary()`, `*float()`, `*double()`,
`*bool()`
- `*and[pattern ⋯]`
- `*or[pattern ⋯]`
- `*not(pattern)` ?
- `pattern(pattern ⋯)` - match record
- `[pattern ⋯]` - match sequence
- `#set{pattern}` - match set
except for `==` etc and `_` and `...`
- if you have to match a label like `*foo` it might clash, so match `<== *foo>` instead:
`<*foo 1 2 3>` ==> `<<== *foo> 1 2 3>`
- `<*int>` for `SignedInteger`, `<*string>`, `<*symbol>`,
`<*bytestring>`/`<*binary>`, `<*float>`, `<*double>`,
`<*bool>`
- `<*and Pattern ⋯>`
- `<*or Pattern ⋯>`
- `<*not Pattern>` ?
- `<Pattern Pattern ⋯>` - match record
- `[Pattern ⋯]` - match sequence
- `#set{Pattern}` - match set
- don't know how to match dictionaries yet
- view it as an interleave of its keyvalues
- `*interleave[pattern ⋯]`?
- `<*interleave Pattern ⋯>`?
- somehow allow specification of a keyvalue that is repeating, that is optional, etc
- `{keypat:valpat ⋯ ...(keypat):...(valpat)}` ??? eww?
- `*group[pattern ⋯]` - sequence of values spliced into wider sequence?
- `{Keypat:Valpat ⋯ <... Keypat>:<... Valpat>}` ??? eww?
- `<*group Pattern ⋯>` - sequence of values spliced into wider sequence?
- use literal `...` symbol (!) to mark repetition in a sequence:
`[*string() ...]`
- could use literal `?` to mark optionality; or better perhaps `*optional(pattern)`,
equivalent to `*biased-choice[pattern *group[]]`; hmm, biased choice!
- could use `*repeat(lo,hi)` or similar for counted repetition
`[<*string> ...]`
- could use literal `?` to mark optionality; or better perhaps `<*optional Pattern>`,
equivalent to `<*biased-choice Pattern <*group>>`; hmm, biased choice!
- could use `<*repeat lo hi>` or similar for counted repetition
- don't know how to write refs to other types yet! def labels starting with `*`?
*def(*foo() *or[*int() *string()]) ?
*foo()
<*def <*foo> <*or <*int> <*string>>>
<*foo>
*def(*maybe(a) *or[nothing() just(a)])
*maybe(*int())
<*def <*maybe a> <*or <nothing> <just a>>>
<*maybe <*int>>
- should those be relative URLs, or jsonpointer or something,
so can drag in types from the web?
@ -285,20 +282,20 @@ The YAML example:
Could be:
[ Database[Username("admin"),
@TODO("get prod passwords out of config") Password("foobar"),
Socket("/var/tmp/database.sock"),
Options[UseUTF8()]],
Memcached[Host("10.0.0.99")],
Workers[Worker("10.0.0.101", 2301),
Worker("10.0.0.102", 2302)] ]
[ <Database [<Username "admin">
@<TODO "get prod passwords out of config"> <Password "foobar">
<Socket "/var/tmp/database.sock">
<Options [<UseUTF8>]>]>
<Memcached [<Host "10.0.0.99">]>
<Workers [<Worker "10.0.0.101" 2301>
<Worker "10.0.0.102" 2302>]> ]
Or
{
database: {
username: "admin",
@TODO("get prod passwords out of config")
@<TODO "get prod passwords out of config">
password: "foobar",
socket: "/var/tmp/database.sock",
options: #set{use_utf8}
@ -306,32 +303,32 @@ Or
memcached: {
host: "10.0.0.99"
},
workers: [ Worker("10.0.0.101", 2301),
Worker("10.0.0.102", 2302) ]
workers: [ <Worker "10.0.0.101" 2301>
<Worker "10.0.0.102" 2302> ]
}
Its schema-sketch could be
[ *interleave[ Database[ *interleave[ Username(*string())
Password(*string())
*optional(Socket(*string()))
*optional(Options[*option() ...]) ] ]
Memcached[ Host(*ipv4()) ... ]
Workers[ Worker(*ipv4() *u16()) ... ] ] ]
[ <*interleave <Database [ <*interleave <Username <*string>>
<Password <*string>>
<*optional <Socket <*string>>>
<*optional <Options [<*option> ...]>>> ]>
<Memcached [ <Host <*ipv4>> ... ]>
<Workers [ <Worker <*ipv4> <*u16>> ... ]>> ]
(for the first variant) or
{
database: {
username: *string(),
password: *string(),
*optional(socket): *string(),
*optional(options): #set{*option()}
username: <*string>,
password: <*string>,
<*optional socket>: <*string>,
<*optional options>: #set{<*option>}
},
memcached: {
host: *ipv4()
host: <*ipv4>
},
workers: [ Worker(*ipv4() *u16()) ... ]
workers: [ <Worker <*ipv4> <*u16>> ... ]
}
Annotations will be allowed on any value; but also perhaps on a
@ -352,12 +349,12 @@ to be written:
database:
username: admin
@TODO("get prod passwords out of config")
@<TODO "get prod passwords out of config">
password: foobar
socket: /var/tmp/database.sock
options: use_utf8
memcached:
host: 10.0.0.99
workers:
Worker(10.0.0.101, 2301)
Worker(10.0.0.102, 2302)
<Worker 10.0.0.101 2301>
<Worker 10.0.0.102 2302>