A function call syntax for KDL.
HUG is several things:
- A strict KDL superset: all KDL is valid HUG.
- A syntax and spec for calling functions in KDL documents.
- A standard library of HUG functions.
HUG Is Not An Acronym
- it's pronounced like "hug"
- the file extension is
.hug
- the plural is HUGs
Format: \
NAME
[
[ INPUT
] ]
, where:
NAME
is a KDL bare identifierINPUT
is optional- the
[]
square brackets are required regardless - whitespace may surround the
INPUT
Function calls may be preceded by a type annotation.
The INPUT
is either:
- a document
- a heterogenous list of values or function calls, separated by commas
A function call can be present in the position of:
- a node
- a value
A function call cannot be:
- the name of a node
- the name of a property
- a type annotation
There are functions in the standard library to provide for usecases which would need these.
As bare identifiers cannot contain \
nor []
, there is no KDL syntax conflict.
There are two modes:
-
partial application evaluates a HUG document as far as possible, and outputs either:
- a KDL document (when fully resolved), or
- a HUG document (when partially resolved), with any unresolved functions left in.
-
erroring application does the same as partial application, but produces errors for any leftover/unresolved functions
Function calls are passed these arguments:
- The input document or list, as defined above.
- The type annotation on the function call, if present.
- The output context, as one of:
- Node (1)
- Value (2)
- Input (3)
A function is always only called with plain values: all function calls within its input must be fully resolved.
example attribute {
(lucky)\sum[
1, 2, 3,
\double[2]
]
\unknown[]
}
In the example above:
double
is called with arguments:input: [Value(2)], type: None, context: Input
sum
is called with arguments:input: [Value(1), Value(2), Value(3), Value(4)], type: Some(lucky), context: Node
unknown
is not a known function, and is left in place- The document resolves to:
example attribute { (lucky)"4" \unknown[] }
- In erroring mode, the following error is emitted: "unresolved function
\unknown[]
at line 7:4".
A function can either:
- succeed, and output as below;
- not apply, and remain as an unapplied function call;
- error.
A function can output:
- a document
- a function call
- a single value
- a heterogenous list of values or function calls
However, some output types are restricted by the context
argument:
- with
context: Node
, only documents and function calls can be produced; - with
context: Value
, only single values and function calls can be produced.
Outputs are merged into their surroundings in different ways. Generally, the output of a function call replaces it as if it had been written in the call's place. Except:
- with
context: Node
and a document output: all top-level nodes in the document are inserted in the place of the function call. - with
context: Input
and a list of values output: the list is unpacked (1, 2, \id[3, 4], 5
resolves to1, 2, 3, 4, 5
).
TODO
Takes a string of Base64 data. The string may span multiple lines: inner whitespace will be ignored. The Base64 alphabet is as in IETF RFC3548.
quote text=\base64_decode["
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24
gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2
YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZ
WRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
"]
// resolves to:
quote text=\base64_decode["TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="]
// or (implementation dependent):
quote text="Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."
Takes a string and returns its Base64 representation. The Base64 alphabet is as in IETF RFC3548. The output will have no newlines or whitespace.
quote text=\base64_encode["Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."]
// resolves to:
quote text="TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
Currently this syntax does not allow you to negate a single type, only a union.
Also, I'd like to question the rationale for why the type syntax is needed. What is the use case?