-
-
Notifications
You must be signed in to change notification settings - Fork 4
data
Angle usually uses the wasp data format:
person{name="Joe"}
person{name:"Joe" number:12345 address:{street=…}}
Everything is a node internally. Nodes have internal primitive types:
In data, without evaluation these groupings are similar:
{1 2 3} [1 2 3] (1 2 3)
all denote a list with 3 elements.
{a:1 b:2 c:3} [a:1 b:2 c:3] (a:1 b:2 c:3)
all denote a map with 3 elements.
However upon evaluation, compilation and interpretation they can have different semantics.
{}
is the most ambitious of those three groupings:
block, code and closure denoted by {}
are very similar concepts:
- every data with the intention of being evaluated is a block
- every block with concrete binding is code
- every code with a local-only binding is a closure
Active data means that elements will or can be evaluated at compile or runtime:
print(now)
in an active context evaluates now
to the current time
Whether data acts as active evaluated or evaluatable code depends on the context.
To force data being read / passed verbatim, without semantic analysis, use the data
quote
keyword.
There is a subtle difference between
person{name:"Joe" address{street:"no way 123"}}
person:{name="Joe" address:{street="no way 123"}}
While both construct an object person
, the variant with colon constructs pure data while the variant without colon
constructs the person via a constructor, if available.
So if previously type person is defined like
a person has a random id
then Joe will automatically derive that id if constructed as person{name:"Joe"}.
The pure data built with person:{name="Joe"} only has a soft-type of person, an elusive unenforced type hint.
Apart from the above canonical format, Angle can also consume lisp/wasp
/polish-notation style data:
(person (name Joe))
Since these formats have different semantics, the lisp style needs a special keyword to activate the slightly modified parser.
Another slightly different format called kdl treats each line as a node instead of list:
html lang="en" {
head {
meta charset="utf-8"
meta name="viewport" content="width=device-width, initial-scale=1.0"
meta \
name="description" \
content="kdl is a document language, mostly based on SDLang, with xml-like semantics"
title "kdl - Kat's Document Language"
link rel="stylesheet" href="/styles/global.css"
}
body {
main {
h1 class="text-4xl text-center" "kdl - Kat's Document Language"
section class="kdl-section" id="description" {
p {
- "kdl is a document language, mostly based on "
a href="https://sdlang.org" "SDLang"
- " with xml-like semantics that looks like you're invoking a bunch of CLI commands"
}
p "It's meant to be used both as a serialization format and a configuration language, and is light compared to XML."
}
}
}
}
To illustrate the difference, mutable x=7
is parsed as (mutable x)=7
in wasp and mutable[x=7]
in kdl. Another difference is a significant white space behind node ids: form {}
in wasp is a compile time ambiguity.
The only thing I don't like in kdl are
- string values need to be quoted
- the
-
for text node_pointer without name/identifier/key. The (false) reason is that quotes at the beginning of node_pointer denote complex identifiers: person "home address":berlin This is fine, but the distinguishing syntax role should be: if a quoted node is empty it is a text node
With that rule both formats are nearly compatible and the remaining difference can be put behind a parser directive or flag. It is really just a question of whether 'space binds stronger than =' as in wasp or not as in kdl.
See significant whitespace and ambiguity
Since these are border cases, there is a compiler pragma/directive/flag to switch to each desired behavior on
demand
e.g. when parsing lisp, sexp, wasp, csv or kdl data; each such mode is also activated via file extension.
These seemingly different data formats are really structurally quite similar an create minimal bearing on the parser.