plumbing.fnk.schema

A very simple type system for a subset of schemas consisting of nested
maps with optional or required keyword keys; used by fnk and kin.

Since schemas are turing-complete and not really designed for type inference,
(and for simplicity) we err on the side of completeness (allowing all legal programs)
at the cost of soundness.

These operations also bake in some logic specific to reasoning about Graphs,
namely that all input keys to a node must be explicitly mentioned as optional or
required, or provided via `instance`, and will thus deliberately drop extra key
schemas on inputs as appropriate.  Output schemas may not have optional keys.

assert-distinct

(assert-distinct things)
Like (assert (distinct? things)) but with a more helpful error message.

assert-iae

macro

(assert-iae form & format-args)
Like assert, but throws a RuntimeException in Clojure (not an AssertionError),
and also takes args to format.

assert-satisfies-schema

(assert-satisfies-schema input-schema output-schema)

compose-schemata

(compose-schemata [i2 o2] [i1 o1])
Inputs: [[i2 o2] :- IOSchemata [i1 o1] :- [(s/one InputSchema (quote input)) (s/one MapOutputSchema (quote output))]]

Given pairs of input and output schemata for fnks f1 and f2,
 return a pair of input and output schemata for #(f2 (merge % (f1 %))).
 f1's output schema must not contain any optional keys.

explicit-schema-key-map

(explicit-schema-key-map s)
Inputs: [s]
Returns: {s/Keyword s/Bool}

Given a possibly-unevaluated map schema, return a map from bare keyword to true
 (for required) or false (for optional)

GraphInputSchema

GraphIOSchemata

guess-expr-output-schema

(guess-expr-output-schema expr)
Guess an output schema for an expr.  Currently just looks for literal map structure and
all keyword keys.

InputSchema

IOSchemata

map-schema?

(map-schema? m)

MapOutputSchema

non-map-diff

(non-map-diff s1 s2)
Return a difference of schmas s1 and s2, where one is not a map.
Punt for now, assuming s2 always satisfies s1.

non-map-union

(non-map-union s1 s2)

OutputSchema

possibly-contains?

(possibly-contains? m k)

required-toplevel-keys

(required-toplevel-keys input-schema)
Inputs: [input-schema :- InputSchema]
Returns: [s/Keyword]

Which top-level keys are required (i.e., non-false) by this input schema.

safe-get

(safe-get m k key-path)
Like (get m k), but throws if k is not present in m.

Schema

schema-diff

(schema-diff input-schema output-schema)
Subtract output-schema from input-schema, returning nil if it's possible that an object
satisfying the output-schema satisfies the input-schema, or otherwise a description
of the part(s) of input-schema not met by output-schema.  Strict about the map structure
of output-schema matching input-schema, but loose about everything else (only looks at
required keys of output-schema.

schema-key

(schema-key m k)

sequence-schemata

(sequence-schemata [i1 o1] [k [i2 o2]])
Inputs: [[i1 o1] :- GraphIOSchemata [k [i2 o2]] :- [(s/one s/Keyword "key") (s/one IOSchemata "inner-schemas")]]
Returns: GraphIOSchemata

Given pairs of input and output schemata for fnks f1 and f2, and a keyword k,
 return a pair of input and output schemata for #(let [v1 (f1 %)] (assoc v1 k (f2 (merge-disjoint % v1))))

split-schema

(split-schema s ks)
Inputs: [s :- InputSchema ks :- [s/Keyword]]

Return a pair [ks-part non-ks-part], with any extra schema removed.

split-schema-keys

(split-schema-keys s)
Inputs: [s :- {s/Keyword s/Bool}]
Returns: [(s/one [s/Keyword] (quote required)) (s/one [s/Keyword] (quote optional))]

Given output of explicit-schema-key-map, split into seq [req opt].

union-input-schemata

(union-input-schemata i1 i2)
Inputs: [i1 :- InputSchema i2 :- InputSchema]
Returns: InputSchema

Returns a minimal input schema schema that entails satisfaction of both s1 and s2

unwrap-schema-form-key

(unwrap-schema-form-key k)
Inputs: [k]
Returns: (s/maybe (s/pair s/Keyword "k" s/Bool "optional?"))

Given a possibly-unevaluated schema map key form, unpack an explicit keyword
 and optional? flag, or return nil for a non-explicit key